我想在后台上传用户的个人资料图片,因为图片可能很大。我将使用Carrierwave + Fog(亚马逊S3)+ Sidekiq。
我可以先没有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来解决。但我想在不使用gem的情况下尝试理解如何做到这一点。
答案 0 :(得分:0)
解决方案是将临时文件的路径传递给SideKiq的worker,并在通过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
<强>更新强>
但是这个解决方案不适用于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