【发布时间】:2016-11-11 06:58:55
【问题描述】:
我想在后台上传用户的个人资料图片,因为图片可能很大。我将为此使用 Carrierwave + Fog (Amazon 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
models/user.rb
mount_uploader :profile_picture, ProfilePictureUploader
它可以完美运行,没有任何麻烦。现在,我想把这项工作交给一个 sidekiq 工作人员。
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 的情况下做到这一点。
【问题讨论】:
-
为什么不能在 Sidekiq 中使用控制器中的相同代码?
User.find(user_id).profile_image = image_path。然后在你的控制器ProfilePictureUploadJob.perform_async(@user.id, params[:profile_picture]) -
@MuradYusufov 我认为 Sidekiq 不接受
ActionDispatch::Http::UploadedFile -
来自api.rubyonrails.org/classes/ActionDispatch/Http/… :上传的文件是临时文件,其生命周期是一个请求。当对象最终确定时,Ruby 会取消链接文件,因此无需使用单独的维护任务来清理它们。所以我不确定您是否可以在请求完成后访问上传的文件。
-
我明白了。你能想到任何可行的解决方案吗?
-
为什么不用carrierwave_backgrounder?
标签: ruby-on-rails sidekiq