2016-04-20 7 views
3

Я работаю над конечной точкой рассылки, которая собирает вложения в качестве Tempfile, тогда мне нужно передать их работнику Sidekiq, чтобы загрузить их в AWS.Rails: Pass Tempfile to Sidekiq

Моя проблема заключается в том, что я застрял в точке, в которой пытаюсь сохранить Tempfile, а затем открываю его в своем рабочем. Я не знаю, с чего я должен открыть свой Tempfile (путь, имя файла ...).

Вот моя функция, которая будет вызывать работника:

if @email 
    # Remove Tempfile autodelete 
    @email.attachments.each {|t| ObjectSpace.undefine_finalizer(t.tempfile)} 

    # Griddler Email to hash for Sidekiq 
    email = { 
     attachments: @email.attachments.map {|att| { 
      type: att.content_type, 
      name: att.original_filename 
     }}, 
     raw_text: @email.raw_text, 
     raw_html: @email.raw_html, 
     from: @email.from, 
     subject: @email.subject, 
     to: @email.to, 
     cc: @email.cc 
    } 

    EmailResponseWorker.perform_async email 
end 

Здесь я использую ObjectSpace.undefine_finalizer(t.tempfile) отключить автоматическое удаление.

Тогда в моей Sidekiq работник:

def perform(email) 
    @email = email 

    attachments = @email['attachments'].inject([]) do |arr, file| 
    object = S3_BUCKET.objects["attachments/#{SecureRandom.uuid}/#{file['name']}"].write(Tempfile.open(file['name']), acl: :public_read) 
    arr << {url: object.public_url.to_s, type: file['type'], name: file['name']} 
    end 
end 

Здесь вложения [ 'имя'] имя файла.

ответ

3

Получить path от TempFile и обработать его как обычный путь к файлу:

path: att.tempfile.path 

это путь к самому TempFile, original_filename имя файла передается клиентом, а не один вам нужно.

Не забудьте отменить связь после успешного завершения работы.

+0

После этого в моем Рабочем я должен использовать 'Tempfile.open (path)'? –

+0

@ IsmaelBourg да. Но лучше, как обычный 'File.open', так что вы можете закрыть и отменить его более явно и не дожидаться, когда GC сгорит – Vasfed

+0

Работает отлично! Благодаря ! –