derivation_endpointplugin has been added, which provides on-the-fly processing functionality, similar to what Dragonfly, Refile, and Active Storage provide. It's suitable for fast transformations, such as generating image thumbnails or document previews.
Rather than encoding processing steps in the URL (like Dragonfly and Active Storage do), with
derivation_endpointyou generate URLs to named "derivation" blocks, passing any arguments you need for the processing.
photo.image.derivation_url(:thumbnail, "600", "400") #=> "derivations/image/thumbnail/600/400/eyJpZCI6ImZvbyIsInN0b3JhZ2UiOiJzdG9yZSJ9?signature=..."
When the URL is requested, it's routed to a Rack app that you mount in your router, which knows how to resolve the HTTP request, call the appropriate processing, and generate an HTTP response.
# config/routes.rb (Rails) Rails.application.routes.draw do mount ImageUploader.derivation_endpoint => "derivations/images" end
In this case the endpoint will call the
:thumbnailderivation block defined in our uploader, passing it the source file and derivation arguments (in this case thumbnail dimensions). We can then generate the thumbnail inside the block:
require "image_processing/mini_magick" class ImageUploader < Shrine derivation :thumbnail do |file, width, height| ImageProcessing::MiniMagick .source(file) .resize_to_limit!(width.to_i, height.to_i) end end
The derivation URLs are signed with the secret key provided when loading the plugin, to prevent tampering and potential DoS attacks.
plugin :derivation_endpoint, secret_key: "<YOUR SECRET KEY>"
derivation_endpointplugin is highly configurable, you can set a CDN host, change response headers of derivatives (
Content-Disposition), add URL expiration, cache generated derivatives to a Shrine storage and more. Check out the documentation for more details.
:marcelMIME type analyzer in
determine_mime_typeplugin now uses the file extension to more accurately determine the correct MIME type.
Shrine.with_fileto return the cached downloaded file for the same
Shrine::UploadedFileobject (instead of copying to a new file each time). However, because the same file object was returned, using
Shrine.with_filewasn't thread safe. This is now fixed by returning a different File object on each invocation (but still pointing to the same file on disk).
Shrine.download_endpointcall provided by the
download_endpointplugin now returns a new Rack app object each time it's called. If you were relying on multiple invocations returning the same object, you will need to modify your code.