2016-11-11 5 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 

, 나는 내가 경로를 통과 할 거라고 생각 일시적으로 업로드 된 파일의 하지만 실제로 사이드 키와 함께 업로드 할 수있는 방법을 찾을 수 없습니다.

이 문제는 Carrierwave_Backgrounder gem을 사용하여 해결할 수 있다고 생각합니다. 그러나 나는 보석을 사용하지 않고 그것을하는 방법을 이해하려고 노력하고 싶었다.

+0

Sidekq의 컨트롤러에서 동일한 코드를 사용할 수없는 이유는 무엇입니까? 'User.find (user_id) .profile_image = image_path'. 그럼 컨트롤러에서'ProfilePictureUploadJob.perform_async (@ user.id, params [: profile_picture])' –

+0

@MuradYusufov 나는 SideK가 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