class ActiveStorage::Service

)
{ local: {service: “Disk”, root: Pathname(“/tmp/foo/storage”) } }
:local,
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.
= Active Storage Service

def build(configurator:, name:, service: nil, **service_config) # :nodoc:

: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:, name:, service: nil, **service_config) # :nodoc:
  new(**service_config).tap do |service_instance|
    service_instance.name = name
  end
end

def compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {})

Concatenate multiple files into a single "composed" file.
def compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {})
  raise NotImplementedError
end

def configure(service_name, configurations)

to set the global Active Storage service when the app boots.
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:)
  disposition = (type.to_s.presence_in(%w( attachment inline )) || "inline")
  ActionDispatch::Http::ContentDisposition.format(disposition: disposition, filename: filename.sanitized)
end

def custom_metadata_headers(metadata)

def custom_metadata_headers(metadata)
  raise NotImplementedError
end

def delete(key)

Delete the file at the +key+.
def delete(key)
  raise NotImplementedError
end

def delete_prefixed(prefix)

Delete files at keys starting with the +prefix+.
def delete_prefixed(prefix)
  raise NotImplementedError
end

def download(key)

Return the content of the file at the +key+.
def download(key)
  raise NotImplementedError
end

def download_chunk(key, range)

Return the partial content in the byte +range+ of the file at the +key+.
def download_chunk(key, range)
  raise NotImplementedError
end

def exist?(key)

Return +true+ if a file exists at the +key+.
def exist?(key)
  raise NotImplementedError
end

def headers_for_direct_upload(key, filename:, content_type:, content_length:, checksum:, custom_metadata: {})

Returns a Hash of headers for +url_for_direct_upload+ requests.
def headers_for_direct_upload(key, filename:, content_type:, content_length:, checksum:, custom_metadata: {})
  {}
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 open(*args, **options, &block)

def open(*args, **options, &block)
  ActiveStorage::Downloader.new(self).open(*args, **options, &block)
end

def private_url(key, expires_in:, filename:, disposition:, content_type:, **)

def private_url(key, expires_in:, filename:, disposition:, content_type:, **)
  raise NotImplementedError
end

def public?

def public?
  @public
end

def public_url(key, **)

def public_url(key, **)
  raise NotImplementedError
end

def service_name

def service_name
  # ActiveStorage::Service::DiskService => Disk
  self.class.name.split("::").third.remove("Service")
end

def update_metadata(key, **metadata)

metadata that has to be updated upon identification.
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)

ensure a match when the upload has completed or raise an ActiveStorage::IntegrityError.
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, **options)

the amount of seconds the URL will be valid for, specified in +expires_in+.
+filename+, and +content_type+ that you wish the file to be served with on request. Additionally, you can also provide
short-lived URL for private files. For private files you can provide the +disposition+ (+:inline+ or +:attachment+),
Returns the URL for the file at the +key+. This returns a permanent URL for public files, and returns a
def url(key, **options)
  instrument :url, key: key do |payload|
    generated_url =
      if public?
        public_url(key, **options)
      else
        private_url(key, **options)
      end
    payload[:url] = generated_url
    generated_url
  end
end

def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {})

that will be uploaded. All these attributes will be validated by the service upon upload.
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:, custom_metadata: {})
  raise NotImplementedError
end