Активное хранилище с Amazon S3 не сохраняется с указанным именем файла, а вместо него используется ключ файла

У меня проблема с Active Storage. Когда я загружаю в Amazon S3, вместо того, чтобы сохранять файл внутри корзины с исходным именем, например myfile.zip, он сохраняет его как key, связанный с этим файлом. Итак, в Cyberduck я вижу что-то вроде этого: 5YE1aJQuFYyWNr6BSHxhQ48t. Без расширения файла.

Я не уверен, есть ли какие-то настройки в Rails 5 или они есть в Amazon S3, но я потратил часы на поиск в Google, чтобы выяснить, почему это происходит.

Любые указатели были бы очень признательны!

С уважением, Андрей


person Drew Potter    schedule 01.06.2018    source источник
comment
Я не работал с Cyberduck, но если вы напишете скрипт для загрузки файлов из корзины, тогда класс Ruby File и Модуль FileUtils может быть полезен для преобразования ключей в пути к файлам и для записи имени файла.   -  person Ginnie Hench    schedule 01.06.2018
comment
Большое спасибо @GinnieHench, это для загрузки, но мне просто было интересно, можно ли изменить фактическое имя файла внутри самого ведра S3. Это должно быть оригинальное имя файла.   -  person Drew Potter    schedule 01.06.2018
comment
@ Дрю, это не так.   -  person George Claghorn    schedule 02.06.2018


Ответы (3)


Это сделано специально из ActiveStorage. Файл хранится с его ключом и без расширения на S3, но когда URL-адрес создается ActiveStorage, задаются расположение и имя файла.

def url(key, expires_in:, filename:, disposition:, content_type:)
  instrument :url, key: key do |payload|
    generated_url = object_for(key).presigned_url :get, expires_in: expires_in.to_i,
      response_content_disposition: content_disposition_with(type: disposition, filename: filename),
      response_content_type: content_type

    payload[:url] = generated_url

    generated_url
  end

конец

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

Подробнее о Content-Disposition заголовках можно узнать здесь .

person Daniel Westendorf    schedule 01.06.2018
comment
Вау, я понятия не имел! Огромное спасибо! Я действительно задавался вопросом, было ли это намеренно! - person Drew Potter; 02.06.2018

Вы все еще можете ссылаться на имя с помощью метода доступа к имени файла.

class User < ApplicationRecord
  has_one_attached :photo
  ...
end

filename = User.first.photo.filename
person Arvin    schedule 03.09.2018

Чтобы иметь собственное имя файла на S3, вы должны обновить как blob.key, так и имя на S3.

Активное хранилище загружает изображения на S3, используя blob.key в качестве пути и имени удаленного изображения.

Для моего использования я только изменил имя для 'вариантов изображений' с помощью Monkey Patch, который позволяет генерировать key, заканчивающийся filename:

config/initializers/active_storate_variant.rb :

ActiveStorage::Variant.class_eval do
  def key
    "variants/#{blob.key}/#{Digest::SHA256.hexdigest(variation.key)}/#{filename}"
  end
end

Поэтому, когда мне нужен общедоступный URL для варианта изображения, я просто вызываю image.url('400x400')

Вот как настроена моя модель изображения:

class Image < ApplicationRecord
  belongs_to :imageable, polymorphic: true
  has_one_attached :picture

  SIZES = { '400x400' => '400x400' }

  def url(size)
    return "https://placehold.it/#{size}" unless picture.attached?

    'https://my_s3_subdomain.amazonaws.com/' +
        picture.variant(resize: SIZES[size]).processed.key
  end

  ...

end

Если у кого-то есть способ получше, я был бы рад его увидеть :)

person Alex    schedule 24.01.2020