7

我最近将以下内容从使用 Paperclip 转换为上传到 Amazon S3 的 Carrierwave,这样我就可以使用carrierwave_direct gem,然后使用 Sidekiq 或其他后台处理 gem。

class Release < ActiveRecord::Base
  has_many :releases_tracks, :dependent => :destroy
  has_many :tracks, :through => :releases_tracks, :order => "releases_tracks.position DESC"
  accepts_nested_attributes_for :tracks, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => :true
  accepts_nested_attributes_for :releases_tracks  
end

class Track < ActiveRecord::Base
  mount_uploader :track, TrackUploader
  has_many :releases_tracks, :dependent => :destroy
  has_many :releases, :through => :releases_tracks 
end

/views/releases/track_upload.html.erb

<%= form_for(@release, :html => { :multipart => true }) do |f| %>
<h3>Upload Tracks for <%= @release.title %></h3>
    <% index = 0 %>
    <%= f.fields_for :tracks do |builder| %>
    <%= @release.tracks[index].name %>
        <%= f.file_field :track, :class => "file styled", :title => 'Select Track'%>
    <% index += 1 %>
    <% end %>

    <%= f.submit "Upload Tracks", :class => "submit" %>
<% end %>

Carrierwave 上传工作正常,但我不知道如何让直接部分工作。部分原因是我不知道如何合并建议的表单代码:

<%= direct_upload_form_for @uploader do |f| %>
  <%= f.file_field :track %>
  <%= f.submit %>
<% end %

或者在我的轨道或发布控制器中我放置建议的位置:

@uploader = User.new.track
@uploader.success_action_redirect = new_user_url

自述文件https://github.com/dwilkie/carrierwave_direct和 Railscast http://railscasts.com/episodes/383-uploading-to-amazon-s3都指向首先上传文件,然后创建数据库条目。在我的应用程序中,数据库条目已经存在。Railscast 确实说这是可能的,但没有通过它。所以这是第一个问题。

第二个是我需要一次上传多个文件。上面的代码确实实现了这一点,但速度很慢,而且它当然会使我的应用程序变得毫无用处。

任何人都可以帮忙吗?提前致谢!

4

1 回答 1

20

首先我建议你不要使用carrierwave_direct,我真的不喜欢这个gem,有很多原因。其中一个原因是,正如文档中所说

请注意,此 gem 仅支持单个文件上传。如果您想同时上传多个文件,则必须使用 javascript 或 flash 上传器。

但如果你想使用它,我猜你必须这样做:

所以首先关于

@uploader = User.new.track
@uploader.success_action_redirect = new_user_url

您似乎正在尝试上传曲目,并且正如您所说的那样,您的模型已经创建,我猜您正在尝试为现有版本上传新曲目。如我错了请纠正我。

所以你应该@uploader#track_upload你的ReleasesController.

class ReleasesController
  ...  
  def track_update 
    @uploader = User.new.track
    @uploader.success_action_redirect = new_user_url
  end
  ...
end

然后在关联的视图 ( /views/releases/track_upload.html.erb) 中,您可以使用direct_upload_form

<%= direct_upload_form_for @uploader do |f| %>
  <%= f.file_field :track %>
  <%= f.submit %>
<% end %>

在您选择文件后,表单将直接将文件上传到 s3。那我不知道具体是怎么做的,但是carrierwave_direct应该会给你上传文件的url。我不确定这一点,因为我从来没有那么远,但想法是你的文件刚刚上传到 s3,现在它必须链接到你的模型,所以文件不会丢失'。所以也许carrierwave_direct通过做一些ajax请求或其他任何事情自己做事情(我怀疑......)。

无论如何,由于您要上传多个文件,我想向您指出我最近写的一个教程

这显示了如何在没有carrierwave_direct 的情况下直接将文件上传到s3,而是自己做。这需要更多的代码和时间,但您可以更好地控制正在发生的事情。

在您的情况下,您需要将我在教程中使用的表单放在您的视图中,即 /views/releases/track_upload.html.erb 视图中。然后,一旦您选择了一个文件,成功的 AJAX 请求(由 jQueryFileUpload 插件发出)将为您提供上传文件的 URL,以便您可以将其保存在 Track 模型中(您可能想要发出一个新的 AJAX 请求到您的服务器以创建新的 Track 模型,或在页面上填充其他表单,例如您在 /views/releases/track_upload.html.erb 文件中使用的表单,然后在提交时将保存轨道。 )我不确定我是否真的很清楚,如果您需要更多解释,请告诉我。

这样做的好处是,如果您只是添加multiple到您的文件输入中,那么很棒的jQueryFileUpload插件将向每个文件发送一个请求到 s3,然后您将在每个 ajax 结果中获得上传文件的 URL:D

你可以调整一些东西来添加进度条,比如使用 jQuery 插件,你真的可以创造出很棒的东西。

希望对你有帮助!

于 2012-10-08T21:49:33.820 回答