Использование нескольких Rails ActiveStorage Services
Я использую ActiveStorage для загрузки PDF-файлов и изображений. PDF-файлы должны храниться локально из-за некоторых проблем конфиденциальности, в то время как изображения должны храниться с помощью Amazon S3. Тем не менее, похоже, что ActiveStorage поддерживает установку только одного типа службы для каждой среды (если только вы не используете функцию зеркалирования, которая в данном случае не выполняет то, что мне нужно).
Есть ли способ использовать разные сервисные конфигурации в одной среде? Например, если модель has_one_attached pdf
он использует локальный сервис:
local:
service: Disk
root: <%= Rails.root.join("storage") %>
И если другая модель has_one_attached image
он использует сервис Amazon:
amazon:
service: S3
access_key_id: ""
secret_access_key: ""
2 ответа
Rails 6.1 теперь поддерживает это.
Согласно этой статье вы можете указатьservice
использовать для каждого attached
:
class MyModel < ApplicationRecord
has_one_attached :private_document, service: :disk
has_one_attached :public_document, service: :s3
end
ActiveStorage хорош, но если вам нужно несколько типов служб для каждой среды, он в настоящее время не будет работать для вас (как упоминал Джордж Клагхорн выше). Если вам нужен альтернативный вариант, я решил эту проблему с помощью Shrine.
Хитрость заключается в том, чтобы настроить несколько "хранилищ" в инициализаторе:
# config/initializers/shrine.rb
Shrine.storages = {
cache: Shrine::Storage::FileSystem.new('storage', prefix: 'uploads/cache'),
pdf_files: Shrine::Storage::FileSystem.new('storage', prefix: 'uploads'),
images: Shrine::Storage::S3.new(**s3_options)
}
А затем используйте плагин default_storage в каждом загрузчике (который вы подключаете к данной модели). Обратите внимание, что это не будет работать, если вы не укажете default_storage в обоих загрузчиках:
class PdfFileUploader < Shrine
plugin :default_storage, cache: :cache, store: :pdf_files
end
class ImageFileUploader < Shrine
plugin :default_storage, cache: :cache, store: :images
end