3

最近、ファイルをS3に直接アップロードするためのpluploadの設定を終了しました。これは、pluploadと組み合わせてS3s投稿方法を使用して行われます。

アップロードが完了した後、モデルをロードし、CarrierWaveのremote_ [uploader] _urlメソッドを使用して、アップロードされたリソースをモデルに割り当てる遅延ジョブをキューに入れます。複数のバージョンを管理するのが簡単なので、CarrierWaveを使用したいと思います。これが私の仕事です(少し編集しましたが、この簡単な例にsend_laterを使用できることに気付きました):

class MediaJob < Struct.new(:medium)
  def perform
    medium.process_file
    medium.save
  end
end

process_fileメソッドは次のとおりです。

def process_file
  self.remote_file_url = s3_original_url
end

その結果、ファイルはS3に3回出入りすることになります。

1)pluploadを使用してS3にアップロード

2)処理のためにCarrierWaveによってダウンロードされます

3)モデルが保存されたときにCarrierWaveによって再アップロードされます

これはすべて、小さなファイルには適していますが、大きなファイルを処理する場合は非常にコストがかかります。#3を排除する方法がなければなりません。元のファイルはすでに存在するため、CarrierWaveが保存時に元のファイルをアップロードしないようにします。ただし、バージョンをアップロードしたいのですが。

4

3 に答える 3

4

だから私は解決策を見つけました。それを始めてくれた貢献者に感謝します。期限が来たところでクレジットが与えられるようにしたいのですが、答えは提案されたものよりも少し複雑でした。

これがうまくいったことです...

1)pluploadがS3へのアップロードを完了した後、ファイル属性(マウントされたCarrierWaveアップローダー)をS3から返されたキーに割り当てました。これは、FileUploadedイベントを使用して別のアクションへの応答を投稿することにより、pluploadで実行されます。

init : {
    FileUploaded: function(up, file, info) {
        $.post('#{media_path}', {s3_response: info.response});
    }
}

2)アクションはその応答を取得し、モデルのメソッドを介してファイル属性(またはマウントされたアップローダーの名前)を割り当てます。

def create
  med = Medium.new_from_s3_response(params[:s3_response])
end

def self.new_from_s3_response(response)
  med = Medium.new

  # Grab filename from response use libxml-ruby gem
  xml = XML::Parser.string(response).parse
  node = xml.find_first('//PostResponse/Key')
  med['file'] = node.content
  med.save

  # Queue up a job to have the file downloaded and processed
  # Note that I am using Mongoid so the handy serialization by DelayedJob doesn't work
  Delayed::Job.enqueue MediaJob.new(med.id)
end

3)ジョブが起動し、process_fileが呼び出されます。このファイルは、オリジナルをダウンロードし、さまざまなバージョンを作成/アップロードします。オリジナルはアップロードされないことに注意してください。任務完了!

class MediaJob < Struct.new(:medium_id)
  def perform
    medium = Medium.find(medium_id)
    medium.process_file

  end
end  

def process_file
  # Download from S3
  file.cache_stored_file!
  # Convert to sanitized file for creating versions
  file.retrieve_from_cache!(file.cache_name)

  # Loop through versions and create them....
  file.versions.values.each do |uploader|
    uploader.store!
  end
end

CarrierWaveGitHubページのwikiエントリからバージョンを作成するためのコードを取得しました。

于 2012-06-22T23:29:08.397 に答える
2

使用する場合はupdate_attribute、コールバックをスキップする必要があります。キャリアウェーブが内部でどのように機能するかはわかりませんが、それを試してみます。

def process_file
  update_attribute(:remote_file_url, s3_original_url)
end

その後、呼び出しをスキップできますsave

別の方法は、に変更saveすることsave(:validate => false)です。

編集:skip_callback検証をスキップするために使用できますhttp://api.rubyonrails.org/classes/ActiveSupport/Callbacks/ClassMethods.html#method-i-skip_callback

于 2012-06-22T14:55:35.993 に答える
0

おそらくあなたは次のようなことを試すことができます(私はs3に保存されたCSVファイルに対してもこのようなことをしました)

1. Download the file to your local directory first 

2. Process the the image (create your version) 

3. And then Upload the file to s3 using fog gem separately 

4. update the remote_url  from the url from the fog gem 

これにより、ステップが3から1に削減されます

s3URLの取得についてはFogのドキュメントを確認できます

この助けを願っています

于 2012-06-22T18:10:48.320 に答える