---
title: Shrine 2.9.0
---

## New Plugins

* The `infer_extension` plugin has been added, which automatically infers
  the upload location extension from the MIME type if it's unknown. This is
  useful when using the `data_uri` plugin (where the extension is always
  unknown), or the `remote_url` plugin (where the extension might not be
  known).

```rb
Shrine.plugin :infer_extension
```

## New Features

* The `determine_mime_type` plugin has gained built-in support for the [Marcel]
  gem, Basecamp's wrapper around the existing [MimeMagic].

```rb
Shrine.plugin :determine_mime_type, analyzer: :marcel
```

* The `versions` plugin now supports saving arrays of files, as well as nested
  structures of arrays and hashes.

```rb
class PdfUploader < Shrine
  plugin :versions
  plugin :processing

  process(:store) do |io, context|
    [ file1, file2, ... ]
    # or
    { name1: [ file1, file2, ... ], ... }
    # or
    [ { name1: file1 }, ... ]
  end
end
```

* `UploadedFile#open` can now be called without passing a block. This is useful
  if you want to make it explicit when the uploaded file is opened, instead of
  it happening automatically when `#read` is called.

```rb
uploaded_file.open  # opens the local or remote file
uploaded_file.read  # read content
uploaded_file.close # close the file
```

* The `Model#<attachment>_attacher` now accepts options which are forwarded to
  `Shrine::Attacher.new`.

```rb
photo.image_attacher(store: :other_store)
photo.update(image: file) # uploads to :other_store
```

## Other improvements

* Fixed `backgrounding` plugin not detecting options passed to
  `Shrine::Attachment.new`.

* Fixed S3 storage replacing whitespace with `+` symbols in original filename
  when assigning object's `:content_disposition` on upload.

* If an error occurs when downloading the file in `UploadedFile#download` and
  `Storage::S3#download`, the tempfile with partially downloaded content will
  now automatically be deleted.

* Shrine now uses the `frozen-string-literal` feature, which will reduce the
  number of string allocations.

## Backwards compatibility

* The `:filename` option of the `data_uri` plugin has been deprecated in favour
  of the new `infer_extension` plugin.

* The `multi_delete` plugin has been deprecated, and the `versions` plugin isn't
  loading it by default anymore.

[Marcel]: https://github.com/basecamp/marcel
[MimeMagic]: https://github.com/minad/mimemagic
