Rails3,S3,Paperclip附件是它自己的型号吗?

所以,我正在开发一个应用程序,用户可以上传和管理照片,并附带一堆行业特定的元数据。

Photo模型中包含所有这些元数据,我正在使用Paperclip将实际图像文件附加到模型并将图像存储在Amazon S3上。

用户交互目前的工作方式如下:

  1. 用户单击“添加照片”并进入“新照片”页面,在该页面中,他将看到一个表单。
  2. 表单上的第一件事是文件选择器。 用户选择文件。
  3. 在此之下是用户填写的几个不同的元数据字段,因此用户填写这些元数据。
  4. 用户点击提交,文件上传并创建新的Photo对象,用户被重定向到不同的页面。

因此,我想做的明显改进是让照片在此过程开始时实际上传,以便在提交提交和重定向到下一页之间没有明显的延迟。 能够在完成上传后向用户显示他们的照片的缩略图预览也是很好的,这样他们就可以在填写表格时看到他们放入元数据的照片。

我认为如果我将图像文件拆分成自己的模型,我可以做到这一点,但我会指的是这样的图像:

@photo.attachment.file.url而不是我现在使用的更简单的@photo.file.url 。 我宁愿不比我更深入地“筑巢”。

此外,将其分为两个模型会引发管理孤儿的问题,我目前无需处理这些问题。

所以我的问题是:

  1. 是否有一种好方法 – 最好使用Flash – 来创建这种异步上传行为而不分成两个模型,或者 –
  2. 如果我必须将元数据和文件拆分为两个模型,是否有办法让Paperclip将附件视为自己的模型,以便我可以使用.而不是.来访问它..

我知道这是一个很大的问题,所以非常感谢您的帮助!

我建议您使用edit操作替换new操作(您可以在用户选择操作时自动创建照片模型。这样,您可以使用Flash上​​传AJAX文件(在某些现代浏览器中支持)执行上传的后备,还可以编辑元数据。要进行上传,请尝试查看plupload或uploadify 。

简单地定义Photo#url有什么问题?

 class Photo def url(*args) attachment.url(*args) end end 

没必要在这里看到。

经过一周的实验,我只是想发布我最后做的事情:

事实上,我确实将照片拆分为两个模型,因为我最终不得不用我尝试的任何方法创建空记录。 我发现最终有两个单独的模型更容易,因为:

  1. 它使得在Rails约定中更容易工作(使用第二个模型的标准REST操作来处理异步更新,而不必向父模型添加多个自定义操作)。

  2. 无论我尝试哪种选项,我最终都会将孤儿记录作为一种可能性。 我发现除非有效(我的情况下是照片模型),并且有可能是孤儿的附件,否则更容易拥有一个永远不会保存的父对象。 附件永远不会直接在应用程序的任何位置调用,因此不存在意外删除空记录的风险,并且无需设置默认范围或某些内容以仅显示“有效”照片。 清理孤儿很容易,只需做Attachment.where( :parent_id => nil )并删除所有这些。

  3. 我可以通过简单地将附件委托给照片来维护以前的代码。 在另一个问题上看到这个答案 。

我希望这能为他人节省一些麻烦。 如果您需要带附件的Ajaxfunction,最好将它们作为自己的模型。 另外,要将ajax文件上传添加到表单,请查看https://github.com/formasfunction/remotipart 。 这保存了我的应用。

只是想知道,你是不是在你的协会上设置了从属条款? 例如,

 Class Photo < ActiveRecord::Base :has_one :attachment, :dependent => :destroy end 

这将阻止孤立记录,因为无论何时在Photo上调用destroy方法,它都会首先执行Photo.attachment.destroy。 它适用于:has_many。

基本上,您将Photo对象的创建分为两部分:上传照片和添加元数据。 在非AJAX站点中,这将是两个单独页面上的两个单独步骤。

我要做的是允许AJAX上传实例化Photo对象,并保存(使用上传的照片)。 然后我会让AJAX代码返回一个对应于会话变量的站点的令牌,让表单知道已经创建了照片的记录。 当用户提交表单的其余部分时,如果存在令牌,则它将知道在已创建的照片对象上填充数据。 如果令牌不存在,它将知道需要从头开始创建Photo对象。