2016-11-11 19 views
0

画像が大きくなる可能性があるため、ユーザーのプロフィール画像をバックグラウンドでアップロードしたいと考えています。私はCarrierwave + Fog(Amazon S3)+ Sidekiqを使用します。Sidekiq + Carrierwave + S3(画像アップロードのバックグラウンド)

私が最初Sidekiqせずにそれを実装することができます

users_controller.rb

def update 
    @user = User.find(params[:id]) 
    if params[:profile_picture] 
    // params[:profile_picture] has ActionDispatch::Http::UploadedFile type 
    @user.profile_image = params[:profile_picture] 
    end 

    ... 
end 

モデル/ user.rb

mount_uploader :profile_picture, ProfilePictureUploader 

それは、任意の手間をかけずに完璧に動作します。今、私はこの仕事をサイドキック労働者に委託したいと思っています。

users_controller.rb

def update 
    @user = User.find(params[:id]) 
    if params[:profile_picture] 
    // Below path is in this kind of form: 
    // /var/folders/ps/l8lvygws0w93trqz7yj1t5sr0000gn/T/RackMultipart20161110-46798-w9bgb9.jpg 
    @user.profile_image = params[:profile_picture].path 
    end 

    ... 
end 

profile_picture_upload_job.rb

class ProfilePictureUploadJob 
    include Sidekiq::Worker 

    def perform(user_id, image_path) 
    user = User.find(user_id) 
    // HELP: I don't know what to do here! 
    user.remote_profile_picture_url = image_path 
    // user.profile_picture = image_path 
    user.save! 
    end 
end 

あなたはRedisのバイナリファイルを渡すことはできませんので、私は、パスを渡す必要があるだろうと思いました一時的にアップロードされたファイルのしかし、私はSidekiqで実際にアップロードする方法を見つけることができません。

これはCarrierwave_Backgrounder gemを使用することで解決できると思います。しかし、私は宝石を使用せずにそれを行う方法を理解しようとしたかった。

+0

サイドキックでコントローラから同じコードを使用するだけの理由はありますか? 'User.find(user_id).profile_image = image_path'です。コントローラの '' ProfilePictureUploadJob.perform_async(@ user.id、params [:profile_picture]) ' –

+0

@MuradYusufov私はSideKrickが' ActionDispatch :: Http :: UploadedFile'を受け入れないと思っています。 –

+0

http://api.rubyonrails。 org/classes/ActionDispatch/Http/UploadedFile.html:アップロードされたファイルは、一時的なファイルであり、その存続期間は1回のリクエストです。オブジェクトがファイナライズされると、Rubyはファイルのリンクを解除するので、別のメンテナンスタスクでそれらを消去する必要はありません。 リクエストが完了してからアップロードしたファイルにアクセスできるかどうかはわかりません。 –

答えて

0

解決策は、一時ファイルへのパスをSideKiqのワーカーに渡し、Carrierwave経由でアップロードする前に開くことです。

users_controller.rb

def update 
    @user = User.find(params[:id]) 
    if params[:profile_picture] 
    // Below path is in this kind of form: 
    // /var/folders/ps/l8lvygws0w93trqz7yj1t5sr0000gn/T/RackMultipart20161110-46798-w9bgb9.jpg 
    @user.profile_image = params[:profile_picture].path 
    end 

    ... 
end 

profile_picture_upload_job.rb

class ProfilePictureUploadJob 
    include Sidekiq::Worker 

    def perform(user_id, image_path) 
    user = User.find(user_id) 
    user.profile_picture = File.open(image_path) 
    user.save! 
    end 
end 

UPDATE:

しかし、このソリューションは、Herokuの上では動作しません。

2016-11-11T11:34:06.839408+00:00 app[worker.1]: 4 TID-osgdwad5o WARN: Errno::ENOENT: No such file or directory @ rb_sysopen - /tmp/RackMultipart20161111-4-1poz958.jpg 
関連する問題