Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using multiple buckets with ActiveStorage

Does anyone know if there is a way to configure custom buckets for specific attachments?

class MyModel < ApplicationRecord
  ...

  has_one_attached :logo, bucket: 'custom_bucket'

  ...    
end
like image 249
Tom Rossi Avatar asked Mar 07 '18 20:03

Tom Rossi


2 Answers

Although there isn't a way to use specific "buckets", one can pretty easily add multiple active storage configurations for multiple buckets (I believe introduced in v6.1):

https://edgeguides.rubyonrails.org/active_storage_overview.html#attaching-files-to-records

For example, you might have a "amazon_s3_cold" and an "amazon_s3_hot", they will have all the same configurations aside from the bucket. You may then configure your buckets accordingly on AWS.

# config/storage.yml

amazon_s3_hot:
   service: S3
   access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
   secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
   region: us-east-1
   bucket: my_hot_bucket
amazon_s3_cold:
   service: S3
   access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
   secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
   region: us-east-1
   bucket: my_cold_bucket

# controllers

class User < ApplicationRecord
    has_one_attached :avatar, service: :amazon_s3_hot
end

class DocumentRecord < ApplicationRecord
    has_one_attached :document_upload, service: :amazon_s3_cold
end

Note - hot/cold doesn't apply to the question directly, but provides some context. Hot/cold storage is a concept pertaining to cloud storage services that trades off costs for access frequencies.

like image 160
karns Avatar answered Nov 17 '22 17:11

karns


You could follow a similar pattern to how a traditional database.yml file inherits settings which is just YML variables. My storage.yml file looks somewhat like this which allows me to store each Active Storage attachment type in their own folder.

The S3 provider which is what powers the DO provider requires a bucket name which I've just specified as 'default' but you could call it 'all' or 'general' and then override only the ones you care about.

(storage.yml)

do: &do
  service: S3
  endpoint: <%= Rails.application.credentials.dig(:digitalocean, :endpoint) %>
  access_key_id: <%= Rails.application.credentials.dig(:digitalocean, :access_key_id) %>
  secret_access_key: <%= Rails.application.credentials.dig(:digitalocean, :secret_access_key) %>
  region: 'nyc3'
  bucket: default

do_user_uploads:
  <<: *do
  bucket: user_uploads

(user.rb)

has_one_attached :upload, service: :do_user_uploads

Hope that helps, I came here looking for the same answer!

like image 1
Nick Hammond Avatar answered Nov 17 '22 18:11

Nick Hammond