Multiple Active Storage Services with Override for Test

Curated ago by @jeremysmithco

Description

Active Storage services default to private access, unless you specifically make them public.

By default, Active Storage assumes private access to services. This means generating signed, single-use URLs for blobs. If you’d rather make blobs publicly accessible, specify public: true in your app’s config/storage.yml

But sometimes apps need both private and public services. For example, User avatars and Account logos could be accessed directly, but Account reports need an authorization check with a redirect to a signed, single-use URL.

You can pass the service option to has_one_attached or has_many_attached, but what if you want to use local storage for running tests? Here’s a way to do that.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

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

amazon_public:
  service: S3
  access_key_id: <%= ENV["AWS_PUBLIC_ACCESS_KEY_ID"] %>
  secret_access_key: <%= ENV["AWS_PUBLIC_SECRET_ACCESS_KEY"] %>
  region: <%= ENV["AWS_PUBLIC_REGION"] %>
  bucket: <%= ENV["AWS_PUBLIC_BUCKET"] %>
  public: true

amazon_private:
  service: S3
  access_key_id: <%= ENV["AWS_PRIVATE_ACCESS_KEY_ID"] %>
  secret_access_key: <%= ENV["AWS_PRIVATE_SECRET_ACCESS_KEY"] %>
  region: <%= ENV["AWS_PRIVATE_REGION"] %>
  bucket: <%= ENV["AWS_PRIVATE_BUCKET"] %>

Specify all Active Storage services in the storage.yml config, using separate S3 buckets for public and private (note public: true on the public bucket configuration).