2013-03-06 2 views
2

Это сводит меня с ума. Я использую CarrierWave с Amazon S3, я могу безопасно загружать файл в ведро, а Im пытается теперь (в другом запросе) извлекать файл и доставлять его в виде загрузки в браузер.CarrierWave S3 File Retrieve Issue - undefined method `body '

Файлы могут быть любыми, .zip-файлами и т. Д. Я не использую его для хранения изображений.

Bucket является закрытым, а не публичным, поэтому я не могу просто использовать URL-адрес S3.

Вот мой получить код:

au = @note.attachment 
au.retrieve_from_store!(File.basename(@note.attachment.to_s)) 
au.cache_stored_file! 

Ошибки кода на cache_stored_file! линия. Бросив ошибку:

undefined method `body' for nil:NilClass 

я осмотреть объект, и это выглядит хорошо для меня, и если я выход @ note.attachment, я могу ясно видеть амазонки s3 URL с ключами и т.д.

Iv были все через Интернет, и я могу понять это. Ив обнаружил несколько людей с тем же вопросом, которые решили его, делая вещи, которые не имеют отношения к моему делу (например, использование какого-либо метода imagemagick), опять же, это всего лишь файлы.

Нет обработки или работы с изображениями, я просто хочу вернуть файлы в браузер в качестве загрузки.

Может ли кто-нибудь помочь?

Вот мой загрузчик:

class AttachmentUploader < CarrierWave::Uploader::Base 

    storage :fog 

    def store_dir 
    "#{Rails.env}/#{model.id}" 
    end 

    def cache_dir 
    "#{Rails.root}/tmp/attachments" 
    end 
end 

и след

carrierwave (0.8.0) lib/carrierwave/storage/fog.rb:225:in `read' 
carrierwave (0.8.0) lib/carrierwave/uploader/cache.rb:77:in `sanitized_file' 
carrierwave (0.8.0) lib/carrierwave/uploader/cache.rb:116:in `cache!' 
carrierwave (0.8.0) lib/carrierwave/uploader/cache.rb:73:in `cache_stored_file!' 

ответ

3

Я думаю, что эти линии не имеют смысла:

au = @note.attachment 
au.retrieve_from_store!(File.basename(@note.attachment.to_s)) 
au.cache_stored_file! 

retrieve_from_store является то, что вы, как правило, называете на загрузчик, а не на прикрепленный объект. Сложный шаг передачи базового имени привязанности к себе должен заставлять предупреждающие колокола гаснуть.

Если вы правильно поняли, вы просто хотите дать пользователю возможность загрузить файл, который вы сохранили в S3.

Вы можете сделать это несколькими способами.

Проще всего позвонить @note.attachment.url и распечатать URL-адрес в качестве ссылки, которую может щелкнуть ваш пользователь.

Другой способ - перенаправить пользователя на url в действие контроллера.

# notes/1/download_attachment 
def download_attachment 
    @note = Note.find(params[:id) 
    redirect_to @note.attachment.url 
end 

Один последний способ действовать в качестве прокси-сервера/кэша, и извлечь файл из S3 и вернуть его.

Вы могли бы сделать это что-то вроде этого в контроллере:

file = open(@note.attachment.url) 
send_data file 

Пожалуйста, обратите внимание, что у меня не было возможности протестировать этот последний фрагмент кода.

Вы можете узнать больше о send_data here.

+0

Спасибо за ваш ответ, это полезно! но как насчет того, являются ли эти файлы безопасными/приватными файлами? Я действительно хочу разоблачить URL-адрес S3? Эти вложения могут быть финансовыми документами, поэтому мне сказали, что мне нужно сначала вытащить файлы в локальный кеш, а затем передать их клиенту. Это верно? – Cheyne

+0

На самом деле у меня похожая ситуация в одном из моих проектов. Что я сделал, так это то, что я использую https для связи с серверами. Я даю пользователям ссылки, но я делаю им временные ссылки, которые истекают очень быстро. Таким образом, злоумышленнику придется как разбить шифрование http, так и сделать это очень быстро, так как срок действия ссылки истечет. Истекающие ссылки легко настраиваются с использованием Carrierwave/Fog. – Jesper

+0

Но вы также можете кэшировать файлы, используя некоторые варианты последнего метода, который я упомянул в своем ответе. – Jesper

Смежные вопросы