Подобные вещи проблематичны с точки зрения Rails из-за способа загрузки изображений. Одна стратегия, чтобы заставить это работать лучше, является:
- Создайте под-форму для загрузки вашего изображения, возможно, используя swfupload , чтобы сделать его более упорядоченным.
- Создайте модель для получения ваших загрузок, которая включает в себя некоторый случайный ключ доступа, используемый для его получения и связывания. Скрепка обрабатывает прикрепленный файл.
- Используйте AJAX, чтобы заполнить основную форму, вставив скрытое поле или, возможно, видимый элемент флажка с соответствующим ключом unique_key, когда завершится подчиненная форма.
Типичная модель выглядит примерно так:
class Avatar < ActiveRecord::Base
has_attached_file :image
# ... Additional Paperclip options here
before_validation :assign_unique_key
belongs_to :user
def to_param
self.unique_key
end
protected
def assign_unique_key
return if (self.unique_key.present?)
self.unique_key = Digest::SHA1.hexdigest(ActiveSupport::SecureRandom.random_number(1<<512).to_s)
end
end
Причина использования поля unique_key заключается в том, что вы можете связать его с формой потенциально несохраненной записи. При вводе его в URL выгодно использовать unique_key вместо id, поскольку трудно сказать, должен ли пользователь видеть эту картинку или нет, когда она загружается, поскольку пользователь-владелец еще не может быть назначен.
Это также не позволяет любопытным людям изменять какой-либо последовательный, легко угадываемый идентификатор в вашем URL и видеть другие загруженные аватары.
Вы можете получить окончательный уменьшенный URL-адрес уменьшенного изображения для Аватара, как и для любой модели на этом этапе.
Вы можете легко убрать параметры при получении и перевести обратно на идентификационные номера Аватара:
# If an avatar_id parameter has been assigned...
if (params[:user][:avatar_id])
# ...resolve this as if it were a unique_key value...
avatar = Avatar.find_by_unique_key(params[:user][:avatar_id])
# ...and repopulate the parameters if it has been found.
params[:user][:avatar_id] = (avatar && avatar.id)
end
# ... params[:user] used as required for create or update
По мере того, как люди загружают и повторно загружают изображения, в конечном итоге у вас будет большое количество потерянных записей, которые фактически нигде не используются. Очень просто написать грабли, чтобы очистить их после того, как прошло достаточно времени. Например:
task :purge_orphan_avatars => :environment do
# Clear out any Avatar records that have not been assigned to a particular
# user within the span of two days.
Avatar.destroy_all([ 'created_at<? AND user_id IS NULL', 2.days.ago ])
end
Использование destroy_all также должно привести к очистке всего материала Paperclip.