简体   繁体   English

是Rails3,S3,回形针附件吗?

[英]Rails3, S3, Paperclip Attachment as it's own model?

So, I'm working on an app where users can upload and manage photos with a bunch of industry specific metadata attached to them. 因此,我正在开发一个应用程序,用户可以在该应用程序上上传和管理带有特定于行业的元数据的照片。

The Photo model has all this metadata in it, and I'm using Paperclip to attach the actual image file to the model and store the images on Amazon S3. Photo模型具有所有这些元数据,并且我正在使用Paperclip将实际图像文件附加到模型并将图像存储在Amazon S3上。

The user interaction currently works like this: 用户交互当前的工作方式如下:

  1. A user clicks "Add Photo" and is taken to the "New Photo" page where he is presented a form. 用户单击“添加照片”,然后转到“新照片”页面,在该页面中向他显示​​一个表单。
  2. The first thing on the form is a file chooser. 表单上的第一件事是文件选择器。 The user selects a file. 用户选择一个文件。
  3. Beneath this are several different fields of metadata for the user to fill out, so the user fills these out. 在此之下是供用户填写的元数据的几个不同字段,因此用户可以填写这些字段。
  4. The user hits submit, the file uploads and a new Photo object is created, the user is redirected to a different page. 用户点击提交,上传文件并创建一个新的Photo对象,将用户重定向到另一个页面。

So, the obvious improvement that I'd like to make is for the photo to actually upload at the beginning of this process so that there isn't such a noticeable delay between hitting submit and being redirected to the next page. 因此,我想做的一个明显改进是,照片实际上是在此过程开始时上传的,因此在单击“提交”和将其重定向到下一页之间没有明显的延迟。 It would also be nice to be able to show the user a thumbnail preview of their photo once it's done uploading, so that they can see the photo they're putting in metadata about as they fill in the form. 能够在完成上传后向用户显示其照片的缩略图预览,这也很好,以便他们在填写表单时可以看到正在放入元数据的照片。

I figure I could make that happen if I split the image file into its own model, but I'd then be referring to the images like so: 我认为,如果我将图像文件分割成自己的模型,就可以实现这一点,但是我会像这样引用图像:

@photo.attachment.file.url instead of the simpler @photo.file.url that I use now. @photo.attachment.file.url而不是我现在使用的更简单的@photo.file.url I'd rather not "nest it" more deeply than I have to. 我宁愿不要“深陷”它。

Also, splitting it into two models raises the issue of managing orphans, which I currently don't have to deal with. 另外,将其分为两个模型也带来了管理孤儿的问题,这是我目前无需处理的问题。

So my questions are: 所以我的问题是:

  1. Is there a good way - preferably not using Flash - to create this asynchronous upload behavior without splitting into two models, OR -- 有没有一种好方法-最好使用Flash-创建这种异步上传行为而不拆分为两个模型,或者-
  2. If I must split the metadata and the file into two models, is there a way to get Paperclip to treat an attachment as its own model so that I can access it using <modelname>.<paperclip_method> instead of <model_name>.<attachment_attribute>.<paperclip_method> ? 如果必须将元数据和文件分成两个模型,是否有办法让Paperclip将附件视为自己的模型,以便我可以使用<modelname>.<paperclip_method>而不是<model_name>.<attachment_attribute>.<paperclip_method>

I know that's a big question, so thank you very much in advance for your help! 我知道这是一个大问题,所以在此先非常感谢您的帮助!

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

What's wrong with simply defining Photo#url like so? 像这样简单地定义Photo#url有什么问题?

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

No need to get fancy here. 没必要在这里花哨。

After a week of experimentation I just thought I'd post what I finally did: 经过一周的实验,我以为我会发布最终的内容:

I did in fact split the photo into two models, because I ended up having to create empty records with any approach I tried. 实际上,我确实将照片分成了两个模型,因为最终我不得不使用任何尝试的方法来创建空记录。 I found it was easier in the end to have two seperate models because: 我发现最终拥有两个单独的模型更加容易,因为:

  1. It made it easier to work within Rails convention (use the standard REST actions for the second model to handle asynchronous updates, rather than having to add several custom actions to the parent model). 它使在Rails约定中的工作变得更加容易(使用第二个模型的标准REST操作来处理异步更新,而不必向父模型添加几个自定义操作)。

  2. No matter which option I tried I ended up having orphan records as a possibility. 无论我尝试哪种选择,我最终都可能会有孤立记录。 I found it was easier to have a parent object which does not ever save unless valid (the Photo model in my case), and to have attachments which may be orphans. 我发现拥有一个永远不会保存的父对象(除非是有效的)(在我的情况下为Photo模型),并带有可能是孤儿的附件,这比较容易。 The attachments are never called directly anywhere in the app, so there's no risk of accidentally having an empty record being pulled up, and no need to set a default scope or something in order to only show "valid" photos. 从未在应用程序中的任何位置直接调用附件,因此不存在意外拉出空白记录的风险,也无需设置默认范围或仅显示“有效”照片的内容。 Cleaning up orphans is pretty easy, just do Attachment.where( :parent_id => nil ) and delete all those. 清理孤儿非常容易,只需执行Attachment.where( :parent_id => nil )并删除所有这些。

  3. I can maintain the previous code by simply delegating attachment to photo. 我可以通过简单地将附件委派给照片来维护先前的代码。 See this answer on another question. 请参阅另一个问题的答案

I hope this saves others some trouble down the road. 我希望这可以避免其他麻烦。 If you need Ajax functionality with attachments it is best to make them their own model. 如果您需要带有附件的Ajax功能,最好使它们成为自己的模型。 Also, for adding ajax file upload to forms, check out https://github.com/formasfunction/remotipart . 另外,要向表单添加ajax文件上传,请查看https://github.com/formasfunction/remotipart This saved my app. 这保存了我的应用程序。

Just wondering, are you not setting the dependent clause on your association? 只是想知道,您是否未在关联中设置从属子句? For example, 例如,

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

This will prevent orphan records, as anytime a destroy method is called on Photo, it'll first do Photo.attachment.destroy. 这将防止孤立记录,因为只要在Photo上调用destroy方法,它将首先执行Photo.attachment.destroy。 It works with :has_many as well. 它也可以和:has_many一起使用。

Basically, you're splitting up the creation of the Photo object into two parts: uploading the photo, and adding the meta-data. 基本上,您将Photo对象的创建分为两个部分:上传照片和添加元数据。 In a non-AJAX site, this would be two separate steps on two separate pages. 在非AJAX网站中,这将是两个单独页面上的两个单独步骤。

What I would do is allow the AJAX upload to instantiate a Photo object, and save it (with the uploaded photo). 我要做的是允许AJAX上传实例化一个Photo对象,并将其保存(与上传的照片一起使用)。 I would then have the AJAX code return a token to the site that corresponds to a session variable to let the form know the record for the photo has already been created. 然后,我将让AJAX代码将令牌返回到与会话变量相对应的站点,以使表单知道已创建照片的记录。 When the user submits the rest of the form, if the token is present, it will know to populate the data on the already created photo object. 当用户提交表单的其余部分时,如果存在令牌,它将知道将数据填充到已经创建的照片对象上。 If the token is not present, it will know it needs to create the Photo object from scratch. 如果令牌不存在,它将知道需要从头开始创建Photo对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM