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
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  class << self
    private

    def storage_service(service)
      return :test if Rails.env.test?

      service
    end
  end
end

The storage_service method will be available to all ActiveRecord objects and will be overridden to the :test service for the test environment.