I want to upload a user's profile picture in the background since the picture can be large. I am going to use Carrierwave + Fog (Amazon S3) + Sidekiq for this.
I can implement it without Sidekiq first:
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
models/user.rb
mount_uploader :profile_picture, ProfilePictureUploader
It works perfectly without any hassle. Now, I want to offload this job to a sidekiq worker.
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
Since you can't pass a binary file to Redis, I thought I'd have to pass the path of the temporarily uploaded file. But I can't find a way to actually upload it with Sidekiq.
I think this can be solved by using Carrierwave_Backgrounder gem. But I wanted to try to understand how to do it without using the gem.
The solution is to pass the path to the temporary file to SideKiq's worker, and opening it before uploading it via 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:
But this solution doesn't work on 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.