---
title: Shrine 2.5.0
---

## New features

* The `add_metadata` plugin has been extended to enable extracting and saving
  multiple metadata values at once. This is useful when you have tools which
  extract various metadata in a single command.

```rb
plugin :add_metadata

add_metadata do |io, context|
  movie = FFMPEG::Movie.new(io.path)

  { "duration"   => movie.duration,
    "bitrate"    => movie.bitrate,
    "resolution" => movie.resolution,
    "frame_rate" => movie.frame_rate }
end

# You can also optionally add metadata reader methods to the UploadedFile
metadata_method :duration, :bitrate, :resolution, :frame_rate
```

* The `UploadedFile#dimensions` method will now be added when loading the
  `store_dimensions` plugin, which returns a two-element array of width and
  height.

```rb
plugin :store_dimensions
```
```rb
uploaded_file = uploader.upload(image)

uploaded_file.width      #=> 500
uploaded_file.height     #=> 400
uploaded_file.dimensions #=> [500, 400] (new)
```

* The `:fallback_original_option` has been added to `versions` plugin, allowing
  you to disable automatic fallback to the cached file when using backgrounding,
  so that you can use a default URL instead.

```rb
plugin :versions, fallback_to_original: false
```

* The `rack_file` plugin now enables the uploaders themselves to accept Rack
  uploaded file hashes for upload, in addition to attachers.

```rb
plugin :rack_file
```
```rb
params[:file] #=> {:tempfile=>#<Tempfile>, :name=>"file", ...}

uploaded_file = uploader.upload(params[:file])
uploaded_file.original_filename #=> "nature.jpg"
uploaded_file.mime_type         #=> "image/jpeg"
```

## Other improvements

* The validation helper methods now also return whether the validation
  suceeded, which makes it much easier to do conditional validation.

```rb
plugin :validation_helpers

Attacher.validate do
  if validate_extension_inclusion %w[jpg jpeg png gif]
    validate_mime_type_inclusion %w[image/jpeg image/png image/gif]
  end
end
```

* A `Attacher.default_url` method has been added to `default_url` plugin, as a
  new idiomatic way of declaring the default URL. This API better communicates
  that the default URL functionality is tied only to the attacher. This block
  is now also evaluated in the context of a `Shrine::Attacher` instance.

```rb
plugin :default_url

Attacher.default_url do |options|
  self   #=> #<Shrine::Attacher>
  name   #=> :image
  record #=> #<Photo>

  "/images/missing/#{name}.jpg"
end
```

* The `validation_helpers` plugin will now match the file extension in a case
  insensitive way, so if you do `validate_extension_inclusion ["jpg"]`, that
  will now also pass for a file named `nature.JPG`.

* The `backgrounding` plugin now also works for plain models, without an ORM.
  Specifically, it doesn't depend on `Attacher.find_record` being defined
  anymore.

* The presign endpoint in the `direct_upload` plugin now allows the `extension`
  query parameter to be passed without a dot.

* If the data hash used for instantiating a `Shrine::UploadedFile` is not
  valid, an explanatory `Shrine::Error` will now be raised. Previously Shrine
  would raise a `KeyError` for a key that was missing.

* Shrine now detects whether two versions point to the same IO object, and
  raises a `Shrine::Error`. Previously the upload would fail with an `IOError`
  when the same IO object would attempt to be uploaded the second time, which
  wasn't very descriptive.

* When `remove_invalid` plugin removes an invalid cached file, it now also
  removes the dirty state from the attacher.

## Backwards compatibility

* Passing a block when loading the `default_url` plugin is now deprecated over
  the new `Attacher.default_url`.

```rb
# deprecated
plugin :default_url do |context|
  "/images/missing/#{context[:name]}.jpg"
end
```

## Documentation

* Added the "Multiple Files" guide describing how to set up multiple file
  uploads using nested association attributes.
