How to add a custom service to ActiveStorage
Add a class in the ActiveStorage::Service
namespace that subclasses ActiveStorage::Service::S3Service
. Override the methods you want to override. For example:
# lib/active_storage/service/cloudfront_s3_service.rb
require "active_storage/service/s3_service"
class ActiveStorage::Service::CloudfrontS3Service < ActiveStorage::Service::S3Service
def url(key, **)
# ...
end
end
Refer to your custom service in config/storage.yml
:
production:
service: CloudfrontS3
access_key_id: ""
secret_access_key: ""
region: ""
bucket: ""
For anyone thats interested, I had a similar issue where by I wanted to use the same flat, single bucket storage, that the S3Service
uses. Its simple enough once you know how:
require "active_storage/service/disk_service"
# S3 uses a flat folder structure, so mimic that so we an sync files and databases
module ActiveStorage
class Service
class FlatDiskService < DiskService
private
def folder_for(_key)
"/"
end
end
end
end
And the config is as follows:
local:
service: FlatDisk
root: <%= Rails.root.join("storage") %>
Edit: I've updated the answer with the amended version that works in Rails 6.