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

时间:2011-01-11 16:52:31

标签: ruby-on-rails model amazon-s3 paperclip attachment

所以,我正在制作一个应用程序,用户可以上传和管理附有大量行业特定元数据的照片。

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

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

  1. 用户点击“添加照片”并进入“新照片”页面,在那里他会看到一张表格。
  2. 表单上的第一件事是文件选择器。用户选择一个文件。
  3. 在此之下是用户填写的几个不同的元数据字段,因此用户填写这些元素。
  4. 用户点击提交,文件上传并创建新的Photo对象,用户将被重定向到其他页面。
  5. 所以,我想做的显而易见的改进是让照片在此过程开始时实际上传,这样在点击提交和重定向到下一页之间就没有明显的延迟。能够在完成上传后向用户显示其照片的缩略图预览也是一件好事,这样他们就可以在填写表格时看到他们放入元数据的照片。

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

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

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

    所以我的问题是:

    1. 有一种好方法 - 最好使用Flash - 创建这种异步上传行为而不分成两个模型,或者 -
    2. 如果我必须将元数据和文件拆分为两个模型,有没有办法让Paperclip将附件视为自己的模型,以便我可以使用<modelname>.<paperclip_method>访问它而不是<model_name>.<attachment_attribute>.<paperclip_method>
    3. 我知道这是一个很大的问题,所以非常感谢您的帮助!

5 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

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

不需要在这里看到。

答案 2 :(得分:1)

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

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

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

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

  3. 我可以通过简单地将附件委托给照片来维护以前的代码。有关其他问题,请参阅this answer

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

答案 3 :(得分:1)

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

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

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

答案 4 :(得分:0)

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

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