class ActiveStorage::Service
)
root: Pathname(“/foo/bar/storage”)
:Disk,
ActiveStorage::Blob.service = ActiveStorage::Service.configure(
can configure the service to use like this:
If you are using Active Storage outside of a Ruby on Rails application, you
config.active_storage.service = :local
use like this:
Then, in your application’s configuration, you can specify the service to
You can checkout the service’s constructor to know which keys are required.
root: <%= Rails.root.join(“storage”) %>
service: Disk
local:
of the aforementioned constant under the service
key. For example:
generated config/storage.yml
file and reference one
Inside a Rails application, you can set-up your services through the
* Mirror
, to be able to use several services to manage attachments.
* AzureStorage
, to manage attachments through Microsoft Azure Storage.
* S3
, to manage attachments through Amazon S3.
* GCS
, to manage attachments through Google Cloud Storage.
* Disk
, to manage attachments saved directly on the hard drive.
The available services are:
Abstract class serving as an interface for concrete services.
def build(configurator:, service: nil, **service_config) #:nodoc:
See MirrorService for an example.
Passes the configurator and all of the service's config as keyword args.
need to build additional services using the configurator.
Override in subclasses that stitch together multiple services and hence
def build(configurator:, service: nil, **service_config) #:nodoc: new(**service_config) end
def configure(service_name, configurations)
typically loaded from a YAML file. The Active Storage engine uses this
Configure an Active Storage service by name from a set of configurations,
def configure(service_name, configurations) Configurator.build(service_name, configurations) end
def content_disposition_with(type: "inline", filename:)
def content_disposition_with(type: "inline", filename:) (type.to_s.presence_in(%w( attachment inline )) || "inline") + "; #{filename.parameters}" end
def delete(key)
def delete(key) raise NotImplementedError end
def delete_prefixed(prefix)
def delete_prefixed(prefix) raise NotImplementedError end
def download(key)
def download(key) raise NotImplementedError end
def download_chunk(key, range)
def download_chunk(key, range) raise NotImplementedError end
def exist?(key)
def exist?(key) raise NotImplementedError end
def headers_for_direct_upload(key, filename:, content_type:, content_length:, checksum:)
def headers_for_direct_upload(key, filename:, content_type:, content_length:, checksum:) {} end
def instrument(operation, payload = {}, &block)
def instrument(operation, payload = {}, &block) ActiveSupport::Notifications.instrument( "service_#{operation}.active_storage", payload.merge(service: service_name), &block) end
def service_name
def service_name # ActiveStorage::Service::DiskService => Disk self.class.name.split("::").third.remove("Service") end
def update_metadata(key, **metadata)
Override in subclasses only if the service needs to store specific
Update metadata for the file identified by +key+ in the service.
def update_metadata(key, **metadata) end
def upload(key, io, checksum: nil, **options)
Upload the +io+ to the +key+ specified. If a +checksum+ is provided, the service will
def upload(key, io, checksum: nil, **options) raise NotImplementedError end
def url(key, expires_in:, disposition:, filename:, content_type:)
of seconds specified in +expires_in+. You most also provide the +disposition+ (+:inline+ or +:attachment+),
Returns a signed, temporary URL for the file at the +key+. The URL will be valid for the amount
def url(key, expires_in:, disposition:, filename:, content_type:) raise NotImplementedError end
def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
You must also provide the +content_type+, +content_length+, and +checksum+ of the file
The URL will be valid for the amount of seconds specified in +expires_in+.
Returns a signed, temporary URL that a direct upload file can be PUT to on the +key+.
def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:) raise NotImplementedError end