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

readme https://github.com/dwilkie/carrierwave_directと Railscast http://railscasts.com/episodes/383-uploading-to-amazon-s3はどちらも、最初にファイルをアップロードしてからデータベース エントリを作成することを示しています。私のアプリでは、db エントリが既に存在します。Railscastはそれが可能だと言っていますが、それを通り抜けていません。それが最初の問題です。

2 つ目は、一度に複数のファイルをアップロードする必要があることです。上記のコードはそれを実現しますが、非常に遅く、もちろん私のアプリはかなり役に立たなくなります。

誰でも助けることができますか?よろしくお願いします!

4

1 に答える 1

20

まず第一に、carrierwave_direct を使用しないことをお勧めします。多くの理由から、私はこの宝石が本当に好きではありません。それらの理由の1つは、ドキュメントで述べられているように

この gem は単一ファイルのアップロードのみをサポートすることに注意してください。複数のファイルを同時にアップロードする場合は、JavaScript またはフラッシュ アップローダーを使用する必要があります。

しかし、それを使用したい場合は、次のことを行う必要があると思います。

では、まずは

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

トラックをアップロードしようとしているようですが、モデルはすでに作成されているとおっしゃっていましたが、既存のリリース用に新しいトラックをアップロードしようとしていると思います。私が間違っている場合は修正してください。

そのため、 のメソッドで@uploadervarを作成する必要があります。#track_uploadReleasesController

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に送信し、アップロードされたファイルのURLを各ajax結果で取得できることです:D

また、プログレス バーを追加するように微調整することもできます。jQuery プラグインを使用すると、本当に素晴らしいものを作成できます。

それがあなたを助けることを願っています!

于 2012-10-08T21:49:33.820 に答える