从 Rails 的角度来看,这种事情可能会有问题,因为图片上传的方式存在难题。为了使其更好地工作,一种策略是:
- 为您的图像上传制作子表单,可能使用 swfupload 使其更加流畅。
- 创建一个模型以接收您的上传内容,包括用于检索和链接它的一些随机访问密钥。Paperclip 处理所附文件。
- 使用 AJAX 通过插入隐藏字段或潜在的可见复选框元素来填充您的主表单,具有适当的 unique_key。
一个典型的模型看起来像这样:
class Avatar < ActiveRecord::Base
has_attached_file :image
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中某种顺序、容易猜测的ID,并查看已上传的其他头像。
您可以像任何模型一样获取Avatar的最终缩略图URL。
在接收到参数后,您可以轻松地剥离它们并将其转换回Avatar ID号码:
if (params[:user][:avatar_id])
avatar = Avatar.find_by_unique_key(params[:user][:avatar_id])
params[:user][:avatar_id] = (avatar && avatar.id)
end
随着人们上传和重新上传图片,你最终会有大量的孤儿记录,这些记录实际上并没有在任何地方使用。编写一个 rake 任务来在合理的时间后清除所有这些记录非常简单。例如:
task :purge_orphan_avatars => :environment do
Avatar.destroy_all([ 'created_at<? AND user_id IS NULL', 2.days.ago ])
end
使用destroy_all方法应该会将所有的Paperclip相关内容全部清除。