---
title: Shrine 3.3.0
---

## New features

* The `:create_on_promote` option has been added to the `derivatives` plugin
  for automatically creating derivatives after the attached cached file is
  promoted to permanent storage.

  ```rb
  Shrine.plugin :derivatives, create_on_promote: true
  ```

* The `:auto_extraction` option has been added to the `store_dimensions` plugin
  for skipping automatically extracting dimensions on upload.

  ```rb
  Shrine.plugin :store_dimensions, auto_extraction: false
  ```

* The `:skip_nil` option has been added to the `add_metadata` plugin for
  excluding metadata keys whose values are nil.

  ```rb
  class PdfUploader < Shrine
    add_metadata :pages, skip_nil: true do |io|
      if is_pdf?(io)
        reader = PDF::Reader.new(io)
        reader.page_count
      else
        # If this is not a PDF, then the pages metadata will not be stored
        nil
      end
    end
  end
  ```

* The `:download` option has been added to derivatives processors in
  `derivatives` plugin for skipping converting the source IO object into a
  file. This can be used to avoid a potentially expensive download/copy when
  the derivatives processor doesn't need the file.

  ```rb
  Attacher.derivatives :my_processor, download: false do |source|
    source #=> Could be File, Shrine::UploadedFile, or other IO-like object
    shrine_class.with_file(source) do |file|
      # can force download/copy if necessary with `with_file`,
    end
  end
  ```

## Bug fixes

* The `upload_endpoint` now handles calling `Shrine.upload_response` method
  from a Rails controller.

* The `derivation_endpoint` plugin now applies the `version` query parameter
  to the derivation when creating the response.

## Other improvements

* The new `Aws:S3::EncryptionV2::Client` is now supported by the S3 storage for
  client-side encryption.

* The `derivation_endpoint` now reduces the possibility of timing attacks by
  comparing URL signatures in constant time using `Rack::Utils.secure_compare`.

* The `derivatives` plugin now copies non-file source IO objects to disk before
  passing them to the processor. This is consistent with how a
  `Shrine::UploadedFile` object is downloaded to disk.

* The `sequel` and `activerecord` plugins now call `Attacher#reload` when
  reloading the model, which reloads the attached files but keeps other
  attacher state.

* The `derivatives` plugin doesn't download the attached file anymore if
  attempting to process derivatives when no derivatives processor was defined.

* The `mirroring` plugin now forwards attacher options when uploading to mirror
  storages.

* The `presign_endpoint` plugin now handles the `OPTIONS` HTTP verb, which
  newer versions of Uppy are requesting.

* `Shrine::Storage::Memory#open` now always returns a `StringIO` in the file
  content's original encoding, instead of the encoding set by
  `Encoding.default_internal`. This works around a [bug][ruby-lang #16497]
  in `StringIO` introduced in Ruby 2.7.0.

* The `remove_attachment` plugin now deletes the removed file if a new file was
  attached right after removal.

## Backwards compatibility

* If you were passing a non-file IO object to the derivatives processor, Shrine
  will now convert it into a file beforehand. If you're currently doing this
  and are converting the IO object into a file inside the processor, you can
  now remove the conversion code to avoid doubling the amount of disk writes.

* When reloading a Sequel/ActiveRecord model, any attacher state other than
  uploaded files will now be retained after the reload. If you were relying on
  all the attacher state being re-initialized, you'll need to update your code.

[ruby-lang #16497]: https://bugs.ruby-lang.org/issues/16497
