Ошибка получения файла CarrierWave S3 - неопределенный метод `body'
Это сводит меня с ума. Я использую CarrierWave с Amazon S3, я могу безопасно загрузить файл в корзину, и сейчас я пытаюсь (в другом запросе) извлечь файл и доставить его как загрузку в браузер.
Файлы могут быть чем угодно, ZIP-файл и т. Д. Я не использую его для хранения изображений.
Bucket является приватным, а не общедоступным, поэтому я не могу просто использовать S3 URL.
Вот мой код восстановления:
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, я ясно вижу URL-адрес amazon s3 с ключами и т. Д.
Я был во всем Интернете, и я могу понять это. 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!'
1 ответ
Я думаю, что эти строки не имеют смысла:
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 здесь.