---
title: Shrine 2.4.0
---

## New features

* The `default_url_options` plugin accepts a block for dynamically generating
options.

```rb
plugin :default_url_options, store: ->(io, **options) do
  {response_content_disposition: "attachment; filename=\"#{io.original_filename}\""}
end
```

* The `activerecord` plugin supports JSON and JSONB PostgreSQL columns.

## Other improvements

* The FileSystem storage doesn't raise an error when attempting to delete a
  file that doesn't exist anymore. This behaviour has also been added to the
  storage linter.

* Fixed `copy` plugin running file validations when assigning copied file,
  which makes it not work with `versions` plugin.

* The S3 storage automatically sets the `Content-Disposition` header with the
  original filename when uploading files.

* The `<attachment>_data` attribute name has been extracted into
  `Attacher#data_attribute`, so that it's possible to override.

* The value conversion around the data attribute has been refactored into
  `#convert_before_write` and `#convert_after_read` on the Attacher, so that
  it can be easily overriden in ORM plugins.

* Work around aws-sdk gem failing if the `:content_disposition` upload option
  was passed to the S3 storage containing non-ASCII characters. This is also
  handled better when generating an URL or presign using the
  `:response_content_disposition` option, by URL-encoding the header value.

* The previous change also makes the `Content-Disposition` option handle
  properly filenames with double quotes.

* `UploadedFile#open` and `UploadedFile#download` don't swallow errors raised
  by `Storage#open` anymore.

* The `sequel` plugin now uses less memory when creating large amount of
  records (see the [Sequel commit] for more details).

* The `download_endpoint` plugin uses Roda's streaming endpoint, which
  integrates better with EventMachine.

* `Shrine::Attachment#to_s` has been added for better introspection when listing
  model ancestors with `puts`.

## Backwards compatibility

* The `download_endpoint` plugin doesn't use the obsolete `Storage#stream`
  method anymore, and instead relies on `Storage#open` to implement streaming.
  All of the public Shrine storages plugins already support streaming `#open`
  for some time, by using `Down::ChunkedIO`.

* Shrine doesn't anymore explicitly unlink Tempfiles returned by `Storage#open`
  after closing them. All external storages already use `Down::ChunkedIO` for
  quite some time, which automatically unlinks the underlying Tempfile when
  `#close` is called. But even if your storage returns Tempfiles, these should
  be automatically unlinked on garbage collection by your Ruby implementation.

* The `:host` option on FileSystem and S3 storage has been moved from a
  first-class storage option passed on `#initialize` to an URL option. The
  original `:host` option still works, but will be removed in Shrine 3.

```rb
# now deprecated
Shrine::Storage::S3.new(host: "http://abc123.cloudfront.net", **s3_options)

# can be passed to #url
s3 = Shrine::Storage::S3.new(**s3_options)
s3.url(host: "http://abc123.cloudfront.net")

# or can be set automatically using `default_url_options` plugin
Shrine.plugin :default_url_options, store: {host: "http://abc123.cloudfront.net"}
```

* Accepting data in form of a JSON string by `Shrine.uploaded_file` has been
  deprecated, `Attacher#uploaded_file` should be used for it instead. Note that
  `Shrine.uploaded_file` will still continue to accept Hash or `UploadedFile`
  objects.

[Sequel commit]: https://github.com/jeremyevans/sequel/commit/ead5e5e09e647f3089ea9e161e99b608c2c6ee02
