Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Multiple Rails ActiveStorage Services

I am using ActiveStorage for uploading PDFs and images. The PDFs need to be stored locally because of some privacy concerns, while the images need to be stored using Amazon S3. However, it looks like ActiveStorage only supports setting one service type per environment (unless you use the mirror functionality, which doesn't do what I need it to in this case).

Is there a way to use different service configs within the same environment? For example, if a model has_one_attached pdf it uses the local service:

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

And if another model has_one_attached image it uses the amazon service:

amazon:
  service: S3
  access_key_id: ""
  secret_access_key: ""
like image 661
Nathan Vanderlaan Avatar asked Sep 01 '25 22:09

Nathan Vanderlaan


2 Answers

Rails 6.1 now supports this.

As per this article, you can specify the service to use for each attached:

class MyModel < ApplicationRecord
  has_one_attached :private_document, service: :disk
  has_one_attached :public_document,  service: :s3
end
like image 68
Joshua Pinter Avatar answered Sep 03 '25 15:09

Joshua Pinter


ActiveStorage is great, but if you're in need of multiple service types per environment it currently won't work for you (as George Claghorn mentioned above). If you need an alternate option, I solved this problem by using Shrine.

The trick is to setup multiple 'stores' in your initializer:

# 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)
}

And then use the default_storage plugin in each uploader (which you connect to a given model). Note that it won't work unless you specify the default_storage in both uploaders:

class PdfFileUploader < Shrine
  plugin :default_storage, cache: :cache, store: :pdf_files
end

class ImageFileUploader < Shrine
  plugin :default_storage, cache: :cache, store: :images
end
like image 25
Nathan Vanderlaan Avatar answered Sep 03 '25 15:09

Nathan Vanderlaan