class ActiveStorage::Variant

avatar.variant(resize: “100x100”, monochrome: true, flip: “-90”)
combine as many as you like freely:
A list of all possible transformations is available at www.imagemagick.org/script/mogrify.php. You can
Then it’ll upload said variant to the service according to a derivative key of the blob and the transformations.
This will create and process a variant of the avatar blob that’s constrained to a height and width of 100.
avatar.variant(resize: “100x100”).processed.service_url
the transformations, upload the variant to the service, and return itself again. Example:
has already been processed and uploaded to the service, and, if so, just return that. Otherwise it will perform
When you do want to actually produce the variant needed, call processed. This will check that the variant
can then produce on-demand.
This will create a URL for that specific blob with that specific variant, which the ActiveStorage::VariantsController
<%= image_tag Current.user.avatar.variant(resize: “100x100”) %>
by Active Storage like so:
To refer to such a delayed on-demand variant, simply link to the variant through the resolved route provided
ActiveStorage::VariantsController.
template, for example. Delay the processing to an on-demand controller, like the one provided in
considerate about when the variant is actually processed. You shouldn’t be processing variants inline in a
into memory. The larger the image, the more memory is used. Because of this process, you also want to be
Note that to create a variant it’s necessary to download the entire blob file from the service and load it
of the file, so you must add gem "mini_magick" to your Gemfile if you wish to use variants.
Variants rely on MiniMagick for the actual transformations
original.
These variants are used to create thumbnails, fixed-size avatars, or any other derivative image from the
Image blobs can have variants that are the result of a set of transformations applied to the original.

def content_type

def content_type
  blob.content_type.presence_in(WEB_IMAGE_CONTENT_TYPES) || "image/png"
end

def download_image

def download_image
  require "mini_magick"
  MiniMagick::Image.create(blob.filename.extension_with_delimiter) { |file| download_blob_to(file) }
end

def filename

def filename
  if WEB_IMAGE_CONTENT_TYPES.include?(blob.content_type)
    blob.filename
  else
    ActiveStorage::Filename.new("#{blob.filename.base}.png")
  end
end

def format(image)

def format(image)
  image.format("PNG") unless WEB_IMAGE_CONTENT_TYPES.include?(blob.content_type)
end

def image

Returns the receiving variant. Allows ActiveStorage::Variant and ActiveStorage::Preview instances to be used interchangeably.
def image
  self
end

def initialize(blob, variation_or_variation_key)

def initialize(blob, variation_or_variation_key)
  @blob, @variation = blob, ActiveStorage::Variation.wrap(variation_or_variation_key)
end

def key

Returns a combination key of the blob and the variation that together identifies a specific variant.
def key
  "variants/#{blob.key}/#{Digest::SHA256.hexdigest(variation.key)}"
end

def open_image(&block)

def open_image(&block)
  image = download_image
  begin
    yield image
  ensure
    image.destroy!
  end
end

def process

def process
  open_image do |image|
    transform image
    format image
    upload image
  end
end

def processed

Returns the variant instance itself after it's been processed or an existing processing has been found on the service.
def processed
  process unless processed?
  self
end

def processed?

def processed?
  service.exist?(key)
end

def service_url(expires_in: service.url_expires_in, disposition: :inline)

for its redirection.
for a variant that points to the ActiveStorage::VariantsController, which in turn will use this +service_call+ method
Use url_for(variant) (or the implied form, like +link_to variant+ or +redirect_to variant+) to get the stable URL

it allows permanent URLs that redirect to the +service_url+ to be cached in the view.
Hiding the +service_url+ behind a redirect also gives you the power to change services without updating all URLs. And
with users. Instead, the +service_url+ should only be exposed as a redirect from a stable, possibly authenticated URL.
Returns the URL of the variant on the service. This URL is intended to be short-lived for security and not used directly
def service_url(expires_in: service.url_expires_in, disposition: :inline)
  service.url key, expires_in: expires_in, disposition: disposition, filename: filename, content_type: content_type
end

def transform(image)

def transform(image)
  variation.transform(image)
end

def upload(image)

def upload(image)
  File.open(image.path, "r") { |file| service.upload(key, file) }
end