Skip to main content

Shrine 2.15.0

New features

  • The derivation_endpoint plugin 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_endpoint you 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 :thumbnail derivation 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>"

    The derivation_endpoint plugin is highly configurable, you can set a CDN host, change response headers of derivatives (Content-Type, Content-Disposition), add URL expiration, cache generated derivatives to a Shrine storage and more. Check out the documentation for more details.

Other improvements

  • The :marcel MIME type analyzer in determine_mime_type plugin now uses the file extension to more accurately determine the correct MIME type.

  • The tempfile plugin modifies Shrine.with_file to return the cached downloaded file for the same Shrine::UploadedFile object (instead of copying to a new file each time). However, because the same file object was returned, using Shrine.with_file wasn'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).

Backwards compatibility

  • The Shrine.download_endpoint call provided by the download_endpoint plugin 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.