2016-11-11 103 views
0

我想在后台上传用户的个人资料图片,因为图片可能很大。我将使用Carrierwave +雾(亚马逊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宝石来解决。但我想尝试了解如何在不使用宝石的情况下做到这一点。

+0

为什么你就不能使用您在Sidekiq控制器相同的代码? 'User.find(user_id).profile_image = image_path'。然后在你的控制器'ProfilePictureUploadJob.perform_async(@ user.id,则params [:profile_picture])' –

+0

@MuradYusufov我觉得Sidekiq不接受'ActionDispatch :: HTTP :: UploadedFile' –

+0

从HTTP://api.rubyonrails。 org/classes/ActionDispatch/Http/UploadedFile.html:上传的文件是临时文件,其寿命是一个请求。当对象完成时,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