This blog is part of our Rails 6.1 series.
Rails 6.1 allows environment-specific configuration files to set up Active Storage.
In development, the config/storage/development.yml file will take precedence over the config/storage.yml file. Similarly, in production, the config/storage/production.yml file will take precedence.
If an environment-specific configuration is not present, Rails will fall back to the configuration declared in config/storage.yml.
Why was it needed?
Before Rails 6.1, all storage services were defined in one file, each environment could set its preferred service in config.active_storage.service, and that service would be used for all attachments.
Now we can override the default application-wide storage service for any attachment, like this:
1class User < ApplicationModel 2 has_one_attached :avatar, service: :amazon_s3 3end
And we can declare a custom amazon_s3 service in the config/storage.yml file:
1amazon_s3: 2 service: S3 3 bucket: "..." 4 access_key_id: "..." 5 secret_access_key: "..."
But we are still using the same service for storing avatars in both production and development environments.
To use a separate service per environment, Rails allows the creation of configuration files for each.
How do we do that?
Let's change the service to something more generic in the User model:
1class User < ApplicationModel 2 has_one_attached :avatar, service: :store_avatars 3end
And add some environment configurations:
For production we'll add config/storage/production.yml:
1store_avatars: 2 service: S3 3 bucket: "..." 4 access_key_id: "..." 5 secret_access_key: "..."
And for development we'll add config/storage/development.yml:
1store_avatars: 2 service: Disk 3 root: <%= Rails.root.join("storage") %>
This will ensure that Rails will store the avatars differently per environment.
Check out the pull request to learn more.