---
title: Shrine 2.12.0
---

## New features

* The `Shrine::Attacher#assign_remote_url` method has been added, which acts the
  same as `#remote_url=` but allows you to also dynamically provide options to
  the underlying downloader (`Down.download` by default).

```rb
attacher.assign_remote_url("https://example.com/image.jpg", downloader: { 'Cookie' => 'abc123' })
```

* The `Shrine::UploadedFile#download_url` method has been added to the
  `download_endpoint` plugin for explicitly generating the file URL through
  the download endpoint.

* The `:redirect` option has been added to `download_endpoint` plugin, which
  makes download URLs redirect directly to the uploaded file on its storage.
  This allows you to avoding streaming the file through your app, and thus not
  having it impact your request throughput.

* The `Shrine::Plugins::ValidationHelpers::PRETTY_FILESIZE` callbable has been
  added, which takes the filesize in bytes and returns the representation in
  correct unit. This can be used when providing custom validation error messages.

```rb
pretty_filesize = Shrine::Plugins::ValidationHelpers::PRETTY_FILESIZE
pretty_filesize.call(1*1024)           #=> "1.0 KB"
pretty_filesize.call(1.5*1024*1024)    #=> "1.5 MB"
pretty_filesize.call(2*1024*1024*1024) #=> "2.0 GB"
```

## Other improvements

* The `Shrine::Storage::FileSystem#open` now forwards any additional options to
  `File.open`.

* The `Shrine::Storage::S3#open` method now accepts the `:rewindable` option to
  disable caching read content to disk.

* In validation error messages in filesize validators in the
  `validation_helpers` plugin show specified limits in the appropriate unit,
  instead of always using megabytes.

* `Shrine::UploadedFile#open` will now always open a new IO object, and close
  the previous one. This way the uploaded file will be reopened if it's closed.

* Fixed possible encoding issues in `Shrine::Storage::S3#upload` when filesize
  is unknown.

* The registered storage resolvers in the `dynamic_storage` plugin are now
  correctly inherited upon subclassing.

* The `:file` MIME type analyzer from `determine_mime_type` plugin will now
  raise an explicit `Shrine::Error` when the subprocess from the shell command
  failed to be spawned.

* `Attacher#data_uri=` and `Attacher#remote_url=` in addition to `""` now also
  ignore `nil` values, instead of raising an exception.

## Backwards compatibility

* The `:storages` option has been deprecated in the `download_endpoint` plugin
  in favour of the new `Shrine::UploadedFile#download_url` method.

* The deprecation of assigning cached versions has been undone, as it can be a
  useful feature.
