shrine 2.19.4 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +485 -43
- data/LICENSE.txt +1 -1
- data/README.md +81 -977
- data/doc/advantages.md +231 -204
- data/doc/attacher.md +304 -153
- data/doc/carrierwave.md +297 -226
- data/doc/changing_derivatives.md +308 -0
- data/doc/changing_location.md +102 -21
- data/doc/changing_storage.md +110 -0
- data/doc/creating_persistence_plugins.md +132 -0
- data/doc/creating_plugins.md +43 -23
- data/doc/creating_storages.md +19 -5
- data/doc/design.md +147 -97
- data/doc/direct_s3.md +38 -28
- data/doc/external/articles.md +63 -0
- data/doc/external/extensions.md +53 -0
- data/doc/external/misc.md +32 -0
- data/doc/getting_started.md +1115 -0
- data/doc/metadata.md +190 -109
- data/doc/multiple_files.md +62 -34
- data/doc/paperclip.md +384 -262
- data/doc/plugins/activerecord.md +177 -46
- data/doc/plugins/add_metadata.md +139 -38
- data/doc/plugins/atomic_helpers.md +217 -0
- data/doc/plugins/backgrounding.md +156 -98
- data/doc/plugins/cached_attachment_data.md +7 -5
- data/doc/plugins/column.md +121 -0
- data/doc/plugins/data_uri.md +23 -22
- data/doc/plugins/default_storage.md +36 -10
- data/doc/plugins/default_url.md +30 -13
- data/doc/plugins/delete_raw.md +4 -2
- data/doc/plugins/derivation_endpoint.md +162 -101
- data/doc/plugins/derivatives.md +829 -0
- data/doc/plugins/determine_mime_type.md +4 -2
- data/doc/plugins/download_endpoint.md +64 -8
- data/doc/plugins/dynamic_storage.md +5 -3
- data/doc/plugins/entity.md +263 -0
- data/doc/plugins/form_assign.md +55 -0
- data/doc/plugins/included.md +31 -8
- data/doc/plugins/infer_extension.md +21 -10
- data/doc/plugins/instrumentation.md +38 -16
- data/doc/plugins/keep_files.md +14 -17
- data/doc/plugins/metadata_attributes.md +42 -13
- data/doc/plugins/mirroring.md +118 -0
- data/doc/plugins/model.md +210 -0
- data/doc/plugins/module_include.md +4 -2
- data/doc/plugins/multi_cache.md +24 -0
- data/doc/plugins/persistence.md +101 -0
- data/doc/plugins/presign_endpoint.md +9 -4
- data/doc/plugins/pretty_location.md +16 -3
- data/doc/plugins/processing.md +4 -2
- data/doc/plugins/rack_file.md +8 -2
- data/doc/plugins/rack_response.md +6 -2
- data/doc/plugins/recache.md +4 -2
- data/doc/plugins/refresh_metadata.md +49 -9
- data/doc/plugins/remote_url.md +84 -47
- data/doc/plugins/remove_attachment.md +27 -6
- data/doc/plugins/remove_invalid.md +21 -6
- data/doc/plugins/restore_cached_data.md +11 -3
- data/doc/plugins/sequel.md +159 -35
- data/doc/plugins/signature.md +16 -5
- data/doc/plugins/store_dimensions.md +14 -2
- data/doc/plugins/tempfile.md +4 -2
- data/doc/plugins/type_predicates.md +96 -0
- data/doc/plugins/upload_endpoint.md +13 -13
- data/doc/plugins/upload_options.md +6 -4
- data/doc/plugins/{default_url_options.md → url_options.md} +9 -7
- data/doc/plugins/validation.md +97 -0
- data/doc/plugins/validation_helpers.md +16 -13
- data/doc/plugins/versions.md +15 -19
- data/doc/processing.md +438 -221
- data/doc/refile.md +185 -167
- data/doc/release_notes/1.0.0.md +4 -0
- data/doc/release_notes/1.1.0.md +6 -2
- data/doc/release_notes/1.2.0.md +4 -0
- data/doc/release_notes/1.3.0.md +4 -0
- data/doc/release_notes/1.4.0.md +4 -0
- data/doc/release_notes/1.4.1.md +4 -0
- data/doc/release_notes/1.4.2.md +4 -0
- data/doc/release_notes/2.0.0.md +4 -0
- data/doc/release_notes/2.0.1.md +4 -0
- data/doc/release_notes/2.1.0.md +4 -0
- data/doc/release_notes/2.1.1.md +4 -0
- data/doc/release_notes/2.10.0.md +4 -0
- data/doc/release_notes/2.10.1.md +4 -0
- data/doc/release_notes/2.11.0.md +4 -0
- data/doc/release_notes/2.12.0.md +4 -0
- data/doc/release_notes/2.13.0.md +4 -0
- data/doc/release_notes/2.14.0.md +5 -1
- data/doc/release_notes/2.15.0.md +11 -7
- data/doc/release_notes/2.16.0.md +4 -0
- data/doc/release_notes/2.17.0.md +4 -0
- data/doc/release_notes/2.18.0.md +4 -0
- data/doc/release_notes/2.19.0.md +6 -3
- data/doc/release_notes/2.2.0.md +4 -0
- data/doc/release_notes/2.3.0.md +4 -0
- data/doc/release_notes/2.3.1.md +4 -0
- data/doc/release_notes/2.4.0.md +4 -0
- data/doc/release_notes/2.4.1.md +4 -0
- data/doc/release_notes/2.5.0.md +4 -0
- data/doc/release_notes/2.6.0.md +4 -0
- data/doc/release_notes/2.6.1.md +4 -0
- data/doc/release_notes/2.7.0.md +4 -0
- data/doc/release_notes/2.8.0.md +4 -0
- data/doc/release_notes/2.9.0.md +4 -0
- data/doc/release_notes/3.0.0.md +981 -0
- data/doc/release_notes/3.0.1.md +22 -0
- data/doc/release_notes/3.1.0.md +73 -0
- data/doc/release_notes/3.2.0.md +96 -0
- data/doc/release_notes/3.2.1.md +31 -0
- data/doc/release_notes/3.2.2.md +14 -0
- data/doc/release_notes/3.3.0.md +105 -0
- data/doc/release_notes/3.4.0.md +35 -0
- data/doc/retrieving_uploads.md +4 -1
- data/doc/securing_uploads.md +60 -37
- data/doc/storage/file_system.md +20 -3
- data/doc/storage/memory.md +19 -0
- data/doc/storage/s3.md +117 -83
- data/doc/testing.md +124 -144
- data/doc/upgrading_to_3.md +710 -0
- data/doc/validation.md +54 -90
- data/lib/shrine/attacher.rb +287 -171
- data/lib/shrine/attachment.rb +13 -46
- data/lib/shrine/plugins/_persistence.rb +93 -0
- data/lib/shrine/plugins/activerecord.rb +77 -34
- data/lib/shrine/plugins/add_metadata.rb +25 -17
- data/lib/shrine/plugins/atomic_helpers.rb +119 -0
- data/lib/shrine/plugins/backgrounding.rb +77 -113
- data/lib/shrine/plugins/cached_attachment_data.rb +6 -15
- data/lib/shrine/plugins/column.rb +102 -0
- data/lib/shrine/plugins/data_uri.rb +38 -36
- data/lib/shrine/plugins/default_storage.rb +45 -15
- data/lib/shrine/plugins/default_url.rb +12 -24
- data/lib/shrine/plugins/default_url_options.rb +3 -30
- data/lib/shrine/plugins/delete_raw.rb +10 -16
- data/lib/shrine/plugins/derivation_endpoint.rb +89 -134
- data/lib/shrine/plugins/derivatives.rb +637 -0
- data/lib/shrine/plugins/determine_mime_type.rb +9 -21
- data/lib/shrine/plugins/download_endpoint.rb +109 -133
- data/lib/shrine/plugins/dynamic_storage.rb +5 -11
- data/lib/shrine/plugins/entity.rb +152 -0
- data/lib/shrine/plugins/form_assign.rb +108 -0
- data/lib/shrine/plugins/included.rb +6 -6
- data/lib/shrine/plugins/infer_extension.rb +13 -20
- data/lib/shrine/plugins/instrumentation.rb +54 -42
- data/lib/shrine/plugins/keep_files.rb +3 -15
- data/lib/shrine/plugins/metadata_attributes.rb +28 -19
- data/lib/shrine/plugins/mirroring.rb +142 -0
- data/lib/shrine/plugins/model.rb +158 -0
- data/lib/shrine/plugins/module_include.rb +3 -3
- data/lib/shrine/plugins/multi_cache.rb +27 -0
- data/lib/shrine/plugins/presign_endpoint.rb +18 -22
- data/lib/shrine/plugins/pretty_location.rb +15 -9
- data/lib/shrine/plugins/processing.rb +22 -9
- data/lib/shrine/plugins/rack_file.rb +2 -42
- data/lib/shrine/plugins/rack_response.rb +15 -10
- data/lib/shrine/plugins/recache.rb +6 -5
- data/lib/shrine/plugins/refresh_metadata.rb +13 -11
- data/lib/shrine/plugins/remote_url.rb +49 -49
- data/lib/shrine/plugins/remove_attachment.rb +10 -6
- data/lib/shrine/plugins/remove_invalid.rb +19 -8
- data/lib/shrine/plugins/restore_cached_data.rb +13 -7
- data/lib/shrine/plugins/sequel.rb +86 -36
- data/lib/shrine/plugins/signature.rb +10 -16
- data/lib/shrine/plugins/store_dimensions.rb +35 -40
- data/lib/shrine/plugins/tempfile.rb +1 -3
- data/lib/shrine/plugins/type_predicates.rb +113 -0
- data/lib/shrine/plugins/upload_endpoint.rb +25 -23
- data/lib/shrine/plugins/upload_options.rb +14 -15
- data/lib/shrine/plugins/url_options.rb +31 -0
- data/lib/shrine/plugins/validation.rb +80 -0
- data/lib/shrine/plugins/validation_helpers.rb +34 -57
- data/lib/shrine/plugins/versions.rb +107 -87
- data/lib/shrine/plugins.rb +22 -0
- data/lib/shrine/storage/file_system.rb +46 -64
- data/lib/shrine/storage/linter.rb +42 -7
- data/lib/shrine/storage/memory.rb +49 -0
- data/lib/shrine/storage/s3.rb +154 -158
- data/lib/shrine/uploaded_file.rb +28 -30
- data/lib/shrine/version.rb +3 -3
- data/lib/shrine.rb +86 -149
- data/shrine.gemspec +9 -10
- metadata +79 -83
- data/doc/migrating_storage.md +0 -76
- data/doc/plugins/backup.md +0 -31
- data/doc/plugins/copy.md +0 -24
- data/doc/plugins/delete_promoted.md +0 -12
- data/doc/plugins/direct_upload.md +0 -172
- data/doc/plugins/hooks.md +0 -58
- data/doc/plugins/logging.md +0 -42
- data/doc/plugins/migration_helpers.md +0 -60
- data/doc/plugins/moving.md +0 -19
- data/doc/plugins/multi_delete.md +0 -20
- data/doc/plugins/parallelize.md +0 -16
- data/doc/plugins/parsed_json.md +0 -23
- data/doc/regenerating_versions.md +0 -143
- data/lib/shrine/plugins/background_helpers.rb +0 -5
- data/lib/shrine/plugins/backup.rb +0 -90
- data/lib/shrine/plugins/copy.rb +0 -50
- data/lib/shrine/plugins/delete_promoted.rb +0 -20
- data/lib/shrine/plugins/direct_upload.rb +0 -217
- data/lib/shrine/plugins/hooks.rb +0 -90
- data/lib/shrine/plugins/logging.rb +0 -142
- data/lib/shrine/plugins/migration_helpers.rb +0 -70
- data/lib/shrine/plugins/moving.rb +0 -57
- data/lib/shrine/plugins/multi_delete.rb +0 -32
- data/lib/shrine/plugins/parallelize.rb +0 -78
- data/lib/shrine/plugins/parsed_json.rb +0 -29
@@ -0,0 +1,981 @@
|
|
1
|
+
---
|
2
|
+
title: Shrine 3.0.0
|
3
|
+
---
|
4
|
+
|
5
|
+
This guide covers all the changes in the 3.0.0 version of Shrine. If you're
|
6
|
+
currently using Shrine 2.x, see **[Upgrading to Shrine 3.x]** for instructions
|
7
|
+
on how to upgrade.
|
8
|
+
|
9
|
+
## Major features
|
10
|
+
|
11
|
+
### Derivatives
|
12
|
+
|
13
|
+
The new **[`derivatives`][derivatives]** plugin has been added for storing
|
14
|
+
additional processed files alongside the main file.
|
15
|
+
|
16
|
+
```rb
|
17
|
+
Shrine.plugin :derivatives
|
18
|
+
```
|
19
|
+
```rb
|
20
|
+
class ImageUploader < Shrine
|
21
|
+
Attacher.derivatives_processor do |original|
|
22
|
+
magick = ImageProcessing::MiniMagick.source(original)
|
23
|
+
|
24
|
+
{
|
25
|
+
large: magick.resize_to_limit!(800, 800),
|
26
|
+
medium: magick.resize_to_limit!(500, 500),
|
27
|
+
small: magick.resize_to_limit!(300, 300),
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
```
|
32
|
+
```rb
|
33
|
+
photo = Photo.new(photo_params)
|
34
|
+
photo.image_derivatives! # creates derivatives
|
35
|
+
photo.save
|
36
|
+
```
|
37
|
+
|
38
|
+
This is a rewrite of the [`versions`][versions] plugin, bringing numerous
|
39
|
+
improvements:
|
40
|
+
|
41
|
+
* processed files are separated from the main file
|
42
|
+
|
43
|
+
```rb
|
44
|
+
photo.image_data #=>
|
45
|
+
# {
|
46
|
+
# "id": "original.jpg",
|
47
|
+
# "storage": "store",
|
48
|
+
# "metadata": { ... },
|
49
|
+
# "derivatives": {
|
50
|
+
# "large": { "id": "large.jpg", "storage": "store", "metadata": { ... } },
|
51
|
+
# "medium": { "id": "medium.jpg", "storage": "store", "metadata": { ... } },
|
52
|
+
# "small": { "id": "small.jpg", "storage": "store", "metadata": { ... } }
|
53
|
+
# }
|
54
|
+
# }
|
55
|
+
|
56
|
+
photo.image #=> #<Shrine::UploadedFile id="original.jpg" ...>
|
57
|
+
photo.image_derivatives #=>
|
58
|
+
# {
|
59
|
+
# large: #<Shrine::UploadedFile id="large.jpg" ...>,
|
60
|
+
# medium: #<Shrine::UploadedFile id="medium.jpg" ...>,
|
61
|
+
# small: #<Shrine::UploadedFile id="small.jpg" ...>,
|
62
|
+
# }
|
63
|
+
```
|
64
|
+
|
65
|
+
* processing is decoupled from promotion
|
66
|
+
|
67
|
+
```rb
|
68
|
+
photo = Photo.create(image: file) # promote original file to permanent storage
|
69
|
+
photo.image_derivatives! # generate derivatives after promotion
|
70
|
+
photo.save # save derivatives data
|
71
|
+
```
|
72
|
+
|
73
|
+
- ability to add or remove processed files at any point
|
74
|
+
|
75
|
+
```rb
|
76
|
+
class ImageUploader < Shrine
|
77
|
+
Attacher.derivatives_processor :thumbnails do |original|
|
78
|
+
# ...
|
79
|
+
end
|
80
|
+
|
81
|
+
Attacher.derivatives_processor :crop do |original, left:, top:, width:, height:|
|
82
|
+
vips = ImageProcessing::Vips.source(original)
|
83
|
+
|
84
|
+
{ cropped: vips.crop!(left, top, width, height) }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
```
|
88
|
+
```rb
|
89
|
+
photo.image_derivatives!(:thumbnails)
|
90
|
+
photo.image_derivatives #=> { large: ..., medium: ..., small: ... }
|
91
|
+
photo.save
|
92
|
+
|
93
|
+
# ... sometime later ...
|
94
|
+
|
95
|
+
photo.image_derivatives!(:crop, left: 0, top: 0, width: 300, height: 300)
|
96
|
+
photo.image_derivatives #=> { large: ..., medium: ..., small: ..., cropped: ... }
|
97
|
+
photo.save
|
98
|
+
```
|
99
|
+
|
100
|
+
* possibility of uploading processed files to different storage
|
101
|
+
|
102
|
+
```rb
|
103
|
+
class ImageUploader < Shrine
|
104
|
+
# specify storage for all derivatives
|
105
|
+
Attacher.derivatives_storage :other_store
|
106
|
+
|
107
|
+
# or specify storage per derivative
|
108
|
+
Attacher.derivatives_storage { |derivative| :other_store }
|
109
|
+
end
|
110
|
+
```
|
111
|
+
```rb
|
112
|
+
photo = Photo.create(image: file)
|
113
|
+
photo.image.storage_key #=> :store
|
114
|
+
|
115
|
+
photo.image_derivatives!
|
116
|
+
photo.image_derivatives[:large].storage_key #=> :other_store
|
117
|
+
```
|
118
|
+
|
119
|
+
### Attacher redesign
|
120
|
+
|
121
|
+
The [`Shrine::Attacher`][attacher] class has been rewritten and can now be
|
122
|
+
used without models:
|
123
|
+
|
124
|
+
```rb
|
125
|
+
attacher = Shrine::Attacher.new
|
126
|
+
attacher.attach(file)
|
127
|
+
attacher.file #=> #<Shrine::UploadedFile>
|
128
|
+
```
|
129
|
+
|
130
|
+
The `Attacher#data`, `Attacher#load_data`, and `Attacher.from_data` methods
|
131
|
+
have been added for dumping and loading the attached file:
|
132
|
+
|
133
|
+
```rb
|
134
|
+
# dump attached file into a serializable Hash
|
135
|
+
data = attacher.data #=> { "id" => "abc123.jpg", "storage" => "store", "metadata" => { ... } }
|
136
|
+
```
|
137
|
+
```rb
|
138
|
+
# initialize attacher from attached file data...
|
139
|
+
attacher = Shrine::Attacher.from_data(data)
|
140
|
+
attacher.file #=> #<Shrine::UploadedFile id="abc123.jpg" storage=:store metadata={...}>
|
141
|
+
|
142
|
+
# ...or load attached file into an existing attacher
|
143
|
+
attacher = Shrine::Attacher.new
|
144
|
+
attacher.load_data(data)
|
145
|
+
attacher.file #=> #<Shrine::UploadedFile>
|
146
|
+
```
|
147
|
+
|
148
|
+
Several more methods have been added:
|
149
|
+
|
150
|
+
- `Attacher#attach` – attaches the file directly to permanent storage
|
151
|
+
- `Attacher#attach_cached` – extracted from `Attacher#assign`
|
152
|
+
- `Attacher#upload` – calls `Shrine#upload`, passing `:record` and `:name` context
|
153
|
+
- `Attacher#file` – alias for `Attacher#get`
|
154
|
+
- `Attacher#cache_key` – returns temporary storage key (`:cache` by default)
|
155
|
+
- `Attacher#store_key` – returns permanent storage key (`:store` by default)
|
156
|
+
|
157
|
+
#### Column
|
158
|
+
|
159
|
+
The new [`column`][column] plugin adds the ability to serialize attached file
|
160
|
+
data, in format suitable for writing into a database column.
|
161
|
+
|
162
|
+
```rb
|
163
|
+
Shrine.plugin :column
|
164
|
+
```
|
165
|
+
```rb
|
166
|
+
# dump attached file data into a JSON string
|
167
|
+
data = attacher.column_data #=> '{"id":"abc123.jpg","storage":"store","metadata":{...}}'
|
168
|
+
```
|
169
|
+
```rb
|
170
|
+
# initialize attacher from attached file data...
|
171
|
+
attacher = Shrine::Attacher.from_column(data)
|
172
|
+
attacher.file #=> #<Shrine::UploadedFile id="abc123.jpg" storage=:store metadata={...}>
|
173
|
+
|
174
|
+
# ...or load attached file into an existing attacher
|
175
|
+
attacher = Shrine::Attacher.new
|
176
|
+
attacher.load_column(data)
|
177
|
+
attacher.file #=> #<Shrine::UploadedFile>
|
178
|
+
```
|
179
|
+
|
180
|
+
#### Entity
|
181
|
+
|
182
|
+
The new [`entity`][entity] plugin adds support for immutable structs, which
|
183
|
+
are commonly used with ROM, Hanami and dry-rb.
|
184
|
+
|
185
|
+
```rb
|
186
|
+
Shrine.plugin :entity
|
187
|
+
```
|
188
|
+
```rb
|
189
|
+
class Photo < Hanami::Entity
|
190
|
+
include Shrine::Attachment(:image)
|
191
|
+
end
|
192
|
+
```
|
193
|
+
```rb
|
194
|
+
photo = Photo.new(image_data: '{"id":"abc123.jpg","storage":"store","metadata":{...}}')
|
195
|
+
photo.image #=> #<Shrine::UploadedFile id="abc123.jpg" storage=:store ...>
|
196
|
+
```
|
197
|
+
|
198
|
+
#### Model
|
199
|
+
|
200
|
+
The new [`model`][model] plugin adds support for mutable structs, which is
|
201
|
+
used by `activerecord` and `sequel` plugins.
|
202
|
+
|
203
|
+
```rb
|
204
|
+
Shrine.plugin :model
|
205
|
+
```
|
206
|
+
```rb
|
207
|
+
class Photo < Struct.new(:image_data)
|
208
|
+
include Shrine::Attachment(:image)
|
209
|
+
end
|
210
|
+
```
|
211
|
+
```rb
|
212
|
+
photo = Photo.new
|
213
|
+
photo.image = file
|
214
|
+
photo.image #=> #<Shrine::UploadedFile id="abc123.jpg" storage=:cache ...>
|
215
|
+
photo.image_data #=> #=> '{"id":"abc123.jpg", "storage":"cache", "metadata":{...}}'
|
216
|
+
```
|
217
|
+
|
218
|
+
### Backgrounding rewrite
|
219
|
+
|
220
|
+
* The [`backgrounding`][backgrounding] plugin has been rewritten for more
|
221
|
+
flexibility and simplicity. The new usage is much more explicit:
|
222
|
+
|
223
|
+
```rb
|
224
|
+
Shrine.plugin :backgrounding
|
225
|
+
Shrine::Attacher.promote_block do
|
226
|
+
PromoteJob.perform_async(self.class.name, record.class.name, record.id, name, file_data)
|
227
|
+
end
|
228
|
+
Shrine::Attacher.destroy_block do
|
229
|
+
DestroyJob.perform_async(self.class.name, data)
|
230
|
+
end
|
231
|
+
```
|
232
|
+
```rb
|
233
|
+
class PromoteJob
|
234
|
+
include Sidekiq::Worker
|
235
|
+
|
236
|
+
def perform(attacher_class, record_class, record.id, name, file_data)
|
237
|
+
attacher_class = Object.const_get(attacher_class)
|
238
|
+
record = Object.const_get(record_class).find(record_id) # if using Active Record
|
239
|
+
|
240
|
+
attacher = attacher_class.retrieve(model: record, name: name, file: file_data)
|
241
|
+
attacher.atomic_promote
|
242
|
+
rescue Shrine::AttachmentChanged, ActiveRecord::RecordNotFound
|
243
|
+
# attachment has changed or the record has been deleted, nothing to do
|
244
|
+
end
|
245
|
+
end
|
246
|
+
```
|
247
|
+
```rb
|
248
|
+
class DestroyJob
|
249
|
+
include Sidekiq::Worker
|
250
|
+
|
251
|
+
def perform(attacher_class, data)
|
252
|
+
attacher_class = Object.const_get(attacher_class)
|
253
|
+
|
254
|
+
attacher = attacher_class.from_data(data)
|
255
|
+
attacher.destroy
|
256
|
+
end
|
257
|
+
end
|
258
|
+
```
|
259
|
+
|
260
|
+
There are several main differences compared to the old implementation:
|
261
|
+
|
262
|
+
- we are in charge of passing the record to the background job
|
263
|
+
- we can access the attacher before promotion
|
264
|
+
- we can react to errors that caused promotion to abort
|
265
|
+
|
266
|
+
We can now also register backgrounding hooks on an attacher instance, allowing
|
267
|
+
us to pass additional parameters to the background job:
|
268
|
+
|
269
|
+
```rb
|
270
|
+
photo = Photo.new(photo_params)
|
271
|
+
|
272
|
+
photo.image_attacher.promote_block do |attacher|
|
273
|
+
PromoteJob.perform_async(
|
274
|
+
attacher.class.name,
|
275
|
+
attacher.record.class.name,
|
276
|
+
attacher.record.id,
|
277
|
+
attacher.name,
|
278
|
+
attacher.file_data,
|
279
|
+
current_user.id, # <== parameters from the controller
|
280
|
+
)
|
281
|
+
end
|
282
|
+
|
283
|
+
photo.save # will call our instance-level backgrounding hook
|
284
|
+
```
|
285
|
+
|
286
|
+
### Persistence interface
|
287
|
+
|
288
|
+
The persistence plugins (`activerecord`, `sequel`) now implement a unified
|
289
|
+
[persistence] interface:
|
290
|
+
|
291
|
+
| Method | Description |
|
292
|
+
| :----------------- | :---------- |
|
293
|
+
| `Attacher#persist` | persists attachment data |
|
294
|
+
| `Attacher#atomic_persist` | persists attachment data if attachment hasn’t changed |
|
295
|
+
| `Attacher#atomic_promote` | promotes cached file and atomically persists changes |
|
296
|
+
|
297
|
+
The "atomic" methods use the new [`atomic_helpers`][atomic_helpers] plugin,
|
298
|
+
and are useful for background jobs. For example, this is how we'd use them to
|
299
|
+
implement metadata extraction in the background in a concurrency-safe way:
|
300
|
+
|
301
|
+
```rb
|
302
|
+
MetadataJob.perform_async(
|
303
|
+
attacher.class.name,
|
304
|
+
attacher.record.class.name,
|
305
|
+
attacher.record.id,
|
306
|
+
attacher.name,
|
307
|
+
attacher.file_data,
|
308
|
+
)
|
309
|
+
```
|
310
|
+
```rb
|
311
|
+
class MetadataJob
|
312
|
+
include Sidekiq::Worker
|
313
|
+
|
314
|
+
def perform(attacher_class, record_class, record_id, name, file_data)
|
315
|
+
attacher_class = Object.const_get(attacher_class)
|
316
|
+
record = Object.const_get(record_class).find(record_id) # if using Active Record
|
317
|
+
|
318
|
+
attacher = attacher_class.retrieve(model: record, name: name, file: file_data)
|
319
|
+
attacher.refresh_metadata! # extract metadata
|
320
|
+
attacher.atomic_persist # persist if attachment hasn't changed
|
321
|
+
rescue Shrine::AttachmentChanged, ActiveRecord::RecordNotFound
|
322
|
+
# attachment has changed or record has been deleted, nothing to do
|
323
|
+
end
|
324
|
+
end
|
325
|
+
```
|
326
|
+
|
327
|
+
## Other new plugins
|
328
|
+
|
329
|
+
* The new [`mirroring`][mirroring] plugin has been added for replicating
|
330
|
+
uploads and deletes to other storages.
|
331
|
+
|
332
|
+
```rb
|
333
|
+
Shrine.storages = { cache: ..., store: ..., backup: ... }
|
334
|
+
|
335
|
+
Shrine.plugin :mirroring, mirror: { store: :backup }
|
336
|
+
```
|
337
|
+
```rb
|
338
|
+
file = Shrine.upload(io, :store) # uploads to :store and :backup
|
339
|
+
file.delete # deletes from :store and :backup
|
340
|
+
```
|
341
|
+
|
342
|
+
* The new [`multi_cache`][multi_cache] plugin has been added for allowing an
|
343
|
+
attacher to accept files from additional temporary storages.
|
344
|
+
|
345
|
+
```rb
|
346
|
+
Shrine.storages = { cache: ..., cache_one: ..., cache_two: ..., store: ... }
|
347
|
+
|
348
|
+
Shrine.plugin :multi_cache, additional_cache: [:cache_one, :cache_two]
|
349
|
+
```
|
350
|
+
```rb
|
351
|
+
photo.image = { "id" => "...", "storage" => "cache", "metadata" => { ... } }
|
352
|
+
photo.image.storage_key #=> :cache
|
353
|
+
# or
|
354
|
+
photo.image = { "id" => "...", "storage" => "cache_one", "metadata" => { ... } }
|
355
|
+
photo.image.storage_key #=> :cache_one
|
356
|
+
# or
|
357
|
+
photo.image = { "id" => "...", "storage" => "cache_two", "metadata" => { ... } }
|
358
|
+
photo.image.storage_key #=> :cache_two
|
359
|
+
```
|
360
|
+
|
361
|
+
* The new [`form_assign`][form_assign] plugin has been added for assigning
|
362
|
+
files directly from form params.
|
363
|
+
|
364
|
+
```rb
|
365
|
+
Shrine.plugin :form_assign
|
366
|
+
```
|
367
|
+
```rb
|
368
|
+
attacher = photo.image_attacher
|
369
|
+
attacher.form_assign({ "image" => file, "title" => "...", "description" => "..." })
|
370
|
+
attacher.file #=> #<Shrine::UploadedFile id="..." storage=:cache ...>
|
371
|
+
```
|
372
|
+
|
373
|
+
## Other features
|
374
|
+
|
375
|
+
* Model file assignment can now be configured to upload directly to permanent
|
376
|
+
storage.
|
377
|
+
|
378
|
+
```rb
|
379
|
+
Shrine.plugin :model, cache: false
|
380
|
+
```
|
381
|
+
```rb
|
382
|
+
photo.image = file
|
383
|
+
photo.image.storage_key #=> :store (permanent storage)
|
384
|
+
```
|
385
|
+
|
386
|
+
* New `Shrine.download_response` method has been added to the
|
387
|
+
`download_endpoint` plugin for generating file response from the controller.
|
388
|
+
|
389
|
+
```rb
|
390
|
+
Rails.application.routes.draw do
|
391
|
+
get "/attachments" => "files#download"
|
392
|
+
end
|
393
|
+
```
|
394
|
+
```rb
|
395
|
+
class FilesController < ApplicationController
|
396
|
+
def download
|
397
|
+
# ... we can now perform things like authentication here ...
|
398
|
+
set_rack_response Shrine.download_response(env)
|
399
|
+
end
|
400
|
+
|
401
|
+
private
|
402
|
+
|
403
|
+
def set_rack_response((status, headers, body))
|
404
|
+
self.status = status
|
405
|
+
self.headers.merge!(headers)
|
406
|
+
self.response_body = body
|
407
|
+
end
|
408
|
+
end
|
409
|
+
```
|
410
|
+
|
411
|
+
* The `Attacher#refresh_metadata!` method has been added to `refresh_metadata`
|
412
|
+
plugin. It refreshes metadata and writes new attached file data back into the
|
413
|
+
data attribute.
|
414
|
+
|
415
|
+
```rb
|
416
|
+
attacher.file.refresh_metadata!
|
417
|
+
attacher.write
|
418
|
+
# can now be shortened to
|
419
|
+
attacher.refresh_metadata!
|
420
|
+
```
|
421
|
+
|
422
|
+
* Including a `Shrine::Attachment` module now defines a `.<name>_attacher`
|
423
|
+
class method on the target class.
|
424
|
+
|
425
|
+
```rb
|
426
|
+
class Photo
|
427
|
+
include ImageUploader::Attachment(:image)
|
428
|
+
end
|
429
|
+
```
|
430
|
+
```rb
|
431
|
+
Photo.image_attacher #=> #<ImageUploader::Attacher ...>
|
432
|
+
```
|
433
|
+
|
434
|
+
* The attachment data serializer is now configurable (by default `JSON`
|
435
|
+
standard library is used):
|
436
|
+
|
437
|
+
```rb
|
438
|
+
require "oj" # https://github.com/ohler55/oj
|
439
|
+
|
440
|
+
Shrine.plugin :column, serializer: Oj
|
441
|
+
```
|
442
|
+
|
443
|
+
* It's now possible to pass options to the validate block via the `:validate`
|
444
|
+
option:
|
445
|
+
|
446
|
+
```rb
|
447
|
+
attacher.assign(file, validate: { foo: "bar" })
|
448
|
+
```
|
449
|
+
```rb
|
450
|
+
class MyUploader < Shrine
|
451
|
+
Attacher.validate do |**options|
|
452
|
+
options #=> { foo: "bar" }
|
453
|
+
end
|
454
|
+
end
|
455
|
+
```
|
456
|
+
|
457
|
+
* Validation can now be skipped on assignment by passing `validate: false`.
|
458
|
+
|
459
|
+
```rb
|
460
|
+
attacher.attach(file, validate: false) # skip validation
|
461
|
+
```
|
462
|
+
|
463
|
+
* Closing the uploaded file can now be prevented by passing `close: false` to
|
464
|
+
`Shrine#upload`.
|
465
|
+
|
466
|
+
* Uploaded file can now be automatically deleted by passing `delete: true` to
|
467
|
+
`Shrine#upload`.
|
468
|
+
|
469
|
+
* New `Attacher#file!` method has been added for retrieving the attached file
|
470
|
+
and raising and exception if it doesn't exist.
|
471
|
+
|
472
|
+
* New `Derivation#opened` method has been added for retrieving an opened
|
473
|
+
derivative in `derivation_endpoint` plugin.
|
474
|
+
|
475
|
+
* New `Storage#delete_prefixed` method has been added for deleting all files
|
476
|
+
in specified directory.
|
477
|
+
|
478
|
+
```rb
|
479
|
+
storage.delete_prefixed("some_directory/")
|
480
|
+
```
|
481
|
+
|
482
|
+
## Performance improvements
|
483
|
+
|
484
|
+
* The attached file is now parsed and loaded from record column only once,
|
485
|
+
which can greatly improve performance if the same attached file is being
|
486
|
+
accessed multiple times.
|
487
|
+
|
488
|
+
```rb
|
489
|
+
photo = Photo.find(photo_id)
|
490
|
+
photo.image # parses and loads attached file
|
491
|
+
photo.image # returns memoized attached file
|
492
|
+
```
|
493
|
+
|
494
|
+
* The `S3#open` method doesn't perform a `#head_obect` request anymore.
|
495
|
+
|
496
|
+
* The `derivation_endpoint` plugin doesn't perform a `Storage#exists?` call
|
497
|
+
anymore when `:upload` is enabled.
|
498
|
+
|
499
|
+
* The `download_endpoint` plugin doesn't perform a `Storage#exists?` call
|
500
|
+
anymore.
|
501
|
+
|
502
|
+
## Other Improvements
|
503
|
+
|
504
|
+
### Core improvements
|
505
|
+
|
506
|
+
* Shrine now works again with MRI 2.3.
|
507
|
+
|
508
|
+
* The memory storage from the [shrine-memory] gem has been merged into core.
|
509
|
+
|
510
|
+
```rb
|
511
|
+
# Gemfile
|
512
|
+
gem "shrine-memory" # this can be removed
|
513
|
+
```
|
514
|
+
|
515
|
+
* The `Attacher#assign` method now accepts cached file data as a Hash.
|
516
|
+
|
517
|
+
```rb
|
518
|
+
photo.image = { "id" => "...", "storage" => "cache", "metadata" => { ... } }
|
519
|
+
````
|
520
|
+
|
521
|
+
* An `UploadedFile` object can now be initialized with symbol keys.
|
522
|
+
|
523
|
+
```rb
|
524
|
+
Shrine.uploaded_file(id: "...", storage: :store, metadata: { ... })
|
525
|
+
```
|
526
|
+
|
527
|
+
* The temporary storage doesn't need to be defined anymore if it's not used.
|
528
|
+
|
529
|
+
* Any changes to `Shrine.storages` will now be applied to existing `Shrine` and
|
530
|
+
`Attacher` instances.
|
531
|
+
|
532
|
+
* When copying the S3 object to another location, any specified upload options
|
533
|
+
will now be applied.
|
534
|
+
|
535
|
+
* Deprecation of passing unknown options to `FileSystem#open` has been
|
536
|
+
reverted. This allows users to continue using `FileSystem` storage in tests
|
537
|
+
as a mock storage.
|
538
|
+
|
539
|
+
* The `Shrine#upload` method now infers file extension from `filename` metadata,
|
540
|
+
making possible to use `filename` to specify file extension.
|
541
|
+
|
542
|
+
```rb
|
543
|
+
file = uploader.upload(StringIO.new("some text"), metadata: { "filename" => "file.txt" })
|
544
|
+
file.id #=> "2a2467ee6acbc5cb.txt"
|
545
|
+
```
|
546
|
+
|
547
|
+
* The `Shrine.opts` hash is now deep-copied on subclassing. This allows plugins
|
548
|
+
to freely mutate hashes and arrays in `Shrine.opts`, knowing they won't be
|
549
|
+
shared across subclasses.
|
550
|
+
|
551
|
+
* The `down` dependency has been updated to `~> 5.0`.
|
552
|
+
|
553
|
+
* The `Shrine::Attachment[]` method has been added as an alternative syntax for
|
554
|
+
creating attachment modules.
|
555
|
+
|
556
|
+
```rb
|
557
|
+
class Photo
|
558
|
+
include ImageUploader::Attachment[:image]
|
559
|
+
end
|
560
|
+
```
|
561
|
+
|
562
|
+
### Plugin improvements
|
563
|
+
|
564
|
+
* The `activerecord` plugin now works with Active Record 3.
|
565
|
+
|
566
|
+
* Callback code from `activerecord` and `sequel` plugin has been moved into
|
567
|
+
attacher methods, allowing the user to override them.
|
568
|
+
|
569
|
+
- `Attacher#(activerecord|sequel)_before_save`
|
570
|
+
- `Attacher#(activerecord|sequel)_after_save`
|
571
|
+
- `Attacher#(activerecord|sequel)_after_destroy`
|
572
|
+
|
573
|
+
* The `url_options` plugin now allows you to override URL options by deleting
|
574
|
+
them.
|
575
|
+
|
576
|
+
```rb
|
577
|
+
uploaded_file.url(response_content_disposition: "attachment")
|
578
|
+
```
|
579
|
+
```rb
|
580
|
+
plugin :url_options, store: -> (io, options) {
|
581
|
+
disposition = options.delete(:response_content_disposition, "inline")
|
582
|
+
|
583
|
+
{
|
584
|
+
response_content_disposition: ContentDisposition.format(
|
585
|
+
disposition: disposition,
|
586
|
+
filename: io.original_filename,
|
587
|
+
)
|
588
|
+
}
|
589
|
+
}
|
590
|
+
```
|
591
|
+
|
592
|
+
* The `:upload_options` hash passed to the uploader is now merged with any
|
593
|
+
options defined with the `upload_options` plugin.
|
594
|
+
|
595
|
+
* The `default_storage` now evaluates the storage block in context of the
|
596
|
+
`Attacher` instance.
|
597
|
+
|
598
|
+
* New `Attacher.default_cache` and `Attacher.default_store` methods have been
|
599
|
+
added to the `default_storage` plugin for declaratively setting default
|
600
|
+
storage.
|
601
|
+
|
602
|
+
```rb
|
603
|
+
Attacher.default_cache { ... }
|
604
|
+
Attacher.default_store { ... }
|
605
|
+
```
|
606
|
+
|
607
|
+
* The `derivation_endpoint` plugin now handles string derivation names.
|
608
|
+
|
609
|
+
* The `Derivation#upload` method from `derivation_endpoint` plugin now accepts
|
610
|
+
additional uploader options
|
611
|
+
|
612
|
+
* The `Derivation#upload` method from `derivation_endpoint` plugin now accepts
|
613
|
+
any IO-like object.
|
614
|
+
|
615
|
+
* The `derivation_endpoint` plugin doesn't re-open `File` objects returned in
|
616
|
+
derivation block anymore.
|
617
|
+
|
618
|
+
* The `instrumentation` plugin now instruments `UploadedFile#open` calls as a
|
619
|
+
new `open.shrine` event. `UploadedFile#download` is still instrumented as
|
620
|
+
`download.shrine`.
|
621
|
+
|
622
|
+
* The `upload.shrine` event now has `:metadata` on the top level in
|
623
|
+
`instrumentation` plugin.
|
624
|
+
|
625
|
+
* The width & height validators in `store_dimensions` plugin don't require
|
626
|
+
`UploadedFile#width` and `UploadedFile#height` methods to be defined anymore,
|
627
|
+
only that the corresponding metadata exists.
|
628
|
+
|
629
|
+
* Any options passed to `Attacher#attach_cached` are now forwarded to metadata
|
630
|
+
extraction when `restore_cached_data` plugin is loaded.
|
631
|
+
|
632
|
+
* The `infer_extension` plugin now works correctly with `pretty_location`
|
633
|
+
plugin when `pretty_location` was loaded after `infer_extension`.
|
634
|
+
|
635
|
+
* The `pretty_location` plugin now accepts `:class_underscore` option for
|
636
|
+
underscoring class names.
|
637
|
+
|
638
|
+
```rb
|
639
|
+
plugin :pretty_location
|
640
|
+
# "blogpost/aa357797-5845-451b-8662-08eecdc9f762/image/493g82jf23.jpg"
|
641
|
+
|
642
|
+
plugin :pretty_location, class_underscore: :true
|
643
|
+
# "blog_post/aa357797-5845-451b-8662-08eecdc9f762/image/493g82jf23.jpg"
|
644
|
+
```
|
645
|
+
|
646
|
+
* You can now load multiple persistence plugins simulatenously, and the correct
|
647
|
+
one will be activated during persistence.
|
648
|
+
|
649
|
+
## Backwards compatibility
|
650
|
+
|
651
|
+
### Plugin deprecation and removal
|
652
|
+
|
653
|
+
* The `backgrounding` plugin has been rewritten and has a new API. While the
|
654
|
+
new API works in a similar way, no backwards compatibility has been kept with
|
655
|
+
the previous API.
|
656
|
+
|
657
|
+
* The `versions`, `processing`, `recache`, and `delete_raw` plugins have been
|
658
|
+
deprecated in favor of the new `derivatives` plugin.
|
659
|
+
|
660
|
+
* The `module_include` plugin has been deprecated over overriding core classes
|
661
|
+
directly.
|
662
|
+
|
663
|
+
* The `hooks`, `parallelize`, `parsed_json`, and `delete_promoted` plugins have
|
664
|
+
been removed.
|
665
|
+
|
666
|
+
* The deprecated `copy`, `backup`, `multi_delete`, `moving`, `logging`,
|
667
|
+
`direct_upload` `background_helpers`, and `migration_helpers` plugins have
|
668
|
+
been removed.
|
669
|
+
|
670
|
+
* The `default_url_options` plugin has been renamed to `url_options`.
|
671
|
+
|
672
|
+
### Attacher API
|
673
|
+
|
674
|
+
* The `Attacher.new` method now only accepts a hash of options, use
|
675
|
+
`Attacher.from_model` for initializing from a model.
|
676
|
+
|
677
|
+
* If you're changing the attachment data column directly, you'll now need to
|
678
|
+
call `Attacher#reload` to make the attacher reflect those changes.
|
679
|
+
|
680
|
+
* The `Attacher#promote` method now only saves the promoted file in memory,
|
681
|
+
it doesn't persist the changes.
|
682
|
+
|
683
|
+
* The `Attacher#_set` and `Attacher#set` methods have been renamed to
|
684
|
+
`Attacher#set` and `Attacher#changed`.
|
685
|
+
|
686
|
+
* The `Attacher#cache!`, `Attacher#store!`, and `Attacher#delete!` methods have
|
687
|
+
been removed.
|
688
|
+
|
689
|
+
* The `Attacher#_promote` and `Attacher#_delete` methods have been removed.
|
690
|
+
|
691
|
+
* The `Attacher#swap`, `Attacher#update`, `Attacher#read`, `Attacher#write`,
|
692
|
+
`Attacher#convert_to_data`, `Attacher#convert_before_write`, and
|
693
|
+
`Attache#convert_after_read` methods have been removed.
|
694
|
+
|
695
|
+
* The `Attacher.validate`, `Attacher#validate` and `Attacher#errors` methods
|
696
|
+
have been extracted into the new `validation` plugin.
|
697
|
+
|
698
|
+
* The `Attacher#data_attribute` method has been renamed to `Attacher#attribute`.
|
699
|
+
|
700
|
+
* The `Attacher#replace` method has been renamed to
|
701
|
+
`Attacher#destroy_previous`.
|
702
|
+
|
703
|
+
* The `Attacher#assign` method now raises an exception when non-cached uploaded
|
704
|
+
file is assigned.
|
705
|
+
|
706
|
+
* The `Attacher#attached?` method now returns whether a file is attached,
|
707
|
+
regardless of whether it was changed or not.
|
708
|
+
|
709
|
+
### Attachment API
|
710
|
+
|
711
|
+
* The `Shrine::Attachment` module doesn't define any instance methods by itself
|
712
|
+
anymore. This has been moved into `entity` and `model` plugins.
|
713
|
+
|
714
|
+
### Uploader API
|
715
|
+
|
716
|
+
* The `:phase` option has been removed.
|
717
|
+
|
718
|
+
* The `Shrine#process` and `Shrine#processed` methods have been removed.
|
719
|
+
|
720
|
+
* The `Shrine#store`, `Shrine#_store`, `Shrine#put`, and `Shrine#copy` methods
|
721
|
+
have been removed.
|
722
|
+
|
723
|
+
* The `Shrine#delete`, `Shrine#_delete`, and `Shrine#remove` methods have been
|
724
|
+
removed.
|
725
|
+
|
726
|
+
* The `Shrine#uploaded?` method has been removed.
|
727
|
+
|
728
|
+
* The `Shrine.uploaded_file` method doesn't yield files anymore by default.
|
729
|
+
|
730
|
+
* The options for `Shrine#upload` and `Shrine#extract_metadata` are now
|
731
|
+
required to have symbol keys.
|
732
|
+
|
733
|
+
* The `Shrine.uploaded_file` method now raises `ArgumentError` on invalid
|
734
|
+
arguments.
|
735
|
+
|
736
|
+
* The `Shrine#upload` method doesn't rescue exceptions that happen in
|
737
|
+
`IO#close` anymore.
|
738
|
+
|
739
|
+
* The deprecated `Shrine::IO_METHODS` constant has been removed.
|
740
|
+
|
741
|
+
### Uploaded File API
|
742
|
+
|
743
|
+
* The `UploadedFile` method now extracts data from the given hash on
|
744
|
+
initialization, it doesn't store the whole hash anymore. This means the
|
745
|
+
following potential code won't work anymore:
|
746
|
+
|
747
|
+
```rb
|
748
|
+
uploaded_file.id #=> "foo"
|
749
|
+
uploaded_file.data["id"] = "bar"
|
750
|
+
uploaded_file.id #=> "foo"
|
751
|
+
```
|
752
|
+
|
753
|
+
* The `UploadedFile#storage_key` method now returns a Symbol instead of a
|
754
|
+
String.
|
755
|
+
|
756
|
+
```rb
|
757
|
+
# previous behaviour
|
758
|
+
uploaded_file.storage_key #=> "store"
|
759
|
+
|
760
|
+
# new behaviour
|
761
|
+
uploaded_file.storage_key #=> :store
|
762
|
+
```
|
763
|
+
|
764
|
+
* The `UploadedFile#==` method now requires both uploaded file objects to be
|
765
|
+
of the same class.
|
766
|
+
|
767
|
+
### Storage API
|
768
|
+
|
769
|
+
* The `Storage#open` method is now required to accept additional options.
|
770
|
+
|
771
|
+
```rb
|
772
|
+
# this won't work anymore
|
773
|
+
def open(id)
|
774
|
+
# ...
|
775
|
+
end
|
776
|
+
|
777
|
+
# this is now required
|
778
|
+
def open(id, **options)
|
779
|
+
# ...
|
780
|
+
end
|
781
|
+
```
|
782
|
+
|
783
|
+
* The `Storage#open` method is now required to raise `Shrine::FileNotFound`
|
784
|
+
exception when the file is missing.
|
785
|
+
|
786
|
+
### S3 API
|
787
|
+
|
788
|
+
* The support for `aws-sdk` 2.x and `aws-sdk-s3` < 1.14 has been removed.
|
789
|
+
|
790
|
+
* `S3#open` now raises `Shrine::FileNotFound` exception when S3 object doesn't
|
791
|
+
exist on the bucket.
|
792
|
+
|
793
|
+
* The `S3#upload` method will now override any S3 object data when copying
|
794
|
+
from another S3 object. If you were relying on S3 object data being inherited
|
795
|
+
on copy, you will need to update your code.
|
796
|
+
|
797
|
+
* The `:host` option in `S3#initialize` has been removed.
|
798
|
+
|
799
|
+
* The `:download` option in `S3#url` has been removed.
|
800
|
+
|
801
|
+
* Specifying `:multipart_threshold` as an integer is not supported anymore.
|
802
|
+
|
803
|
+
* Non URI-escaped `:content_disposition` and `:response_content_disposition`
|
804
|
+
values are not supported anymore.
|
805
|
+
|
806
|
+
* The `S3#presign` method now returns a hash instead of an object for default
|
807
|
+
POST method.
|
808
|
+
|
809
|
+
* The deprecated `S3#stream`, `S3#download`, and `S3#s3` methods have been
|
810
|
+
removed.
|
811
|
+
|
812
|
+
* The `S3#open` method doesn't include an `:object` in `Down::ChunkedIO#data`
|
813
|
+
anymore.
|
814
|
+
|
815
|
+
### FileSystem API
|
816
|
+
|
817
|
+
* `FileSystem#open` now raises `Shrine::FileNotFound` exception when file does
|
818
|
+
not exist on the filesystem.
|
819
|
+
|
820
|
+
* The deprecated `:host` option in `FileSystem#initialize` has been removed.
|
821
|
+
|
822
|
+
* The deprecated `:older_than` option in `FileSystem#clear!` has been removed.
|
823
|
+
|
824
|
+
* The deprecated `FileSystem#download` method has been removed.
|
825
|
+
|
826
|
+
* The `FileSystem#movable?` and `FileSystem#move` methods have been made
|
827
|
+
private.
|
828
|
+
|
829
|
+
* The `FileSystem#open` method doesn't accept a block anymore.
|
830
|
+
|
831
|
+
### Plugins API
|
832
|
+
|
833
|
+
* `remote_url`
|
834
|
+
|
835
|
+
- A custom downloader is now required to raise
|
836
|
+
`Shrine::Plugins::RemoteUrl::DownloadError` in order for the exception to
|
837
|
+
be converted into a validation error. `Down::NotFound` and `Down::TooLarge`
|
838
|
+
exceptions are converted by default. All other exceptions are propagated.
|
839
|
+
|
840
|
+
* `upload_endpoint`
|
841
|
+
|
842
|
+
- The deprecated `Shrine::Plugins::UploadEndpoint::App` constant has been
|
843
|
+
removed.
|
844
|
+
|
845
|
+
- The `:request` option holding the `Rack::Request` object isn't passed to
|
846
|
+
the uploader anymore.
|
847
|
+
|
848
|
+
* `presign_endpoint`
|
849
|
+
|
850
|
+
- `Storage#presign` results that cannot coerce themselves into a Hash are not
|
851
|
+
supported anymore.
|
852
|
+
|
853
|
+
- The deprecated `Shrine::Plugins::PresignEndpoint::App` constant has been
|
854
|
+
removed.
|
855
|
+
|
856
|
+
* `derivation_endpoint`
|
857
|
+
|
858
|
+
- The derivation block is now evaluated in context of a `Shrine::Derivation`
|
859
|
+
instance.
|
860
|
+
|
861
|
+
- The derivation block can now return only `File` and `Tempfile` objects.
|
862
|
+
|
863
|
+
- The `:download_errors` option has been removed, as it's now obsolete.
|
864
|
+
|
865
|
+
- The `:include_uploaded_file` option has been removed, as it's now obsolete.
|
866
|
+
|
867
|
+
- The source `UploadedFile` is not passed to the derivation block anymore
|
868
|
+
on `download: false`.
|
869
|
+
|
870
|
+
- The `Derivation#upload` method now closes the uploaded file.
|
871
|
+
|
872
|
+
- The `derivation.upload` instrumentation event payload now includes only
|
873
|
+
`:derivation` key.
|
874
|
+
|
875
|
+
* `download_endpoint`
|
876
|
+
|
877
|
+
- Support for legacy `/:storage/:id` URLs has been dropped.
|
878
|
+
|
879
|
+
- The `:storages` plugin option has been removed.
|
880
|
+
|
881
|
+
- The `Shrine::Plugins::DownloadEndpoint::App` constant has been removed.
|
882
|
+
|
883
|
+
* `data_uri`
|
884
|
+
|
885
|
+
- The deprecated `:filename` plugin option has been removed.
|
886
|
+
|
887
|
+
- The deprecated `Shrine::Plugins::DataUri::DataFile` constant has been
|
888
|
+
removed.
|
889
|
+
|
890
|
+
* `rack_file`
|
891
|
+
|
892
|
+
- The deprecated `Shrine::Plugins::RackFile::UploadedFile` constant has been
|
893
|
+
removed.
|
894
|
+
|
895
|
+
- Passing a Rack uploaded file hash to `Shrine#upload` is not supported
|
896
|
+
anymore.
|
897
|
+
|
898
|
+
* `cached_attachment_data`
|
899
|
+
|
900
|
+
- The `#<name>_cached_data=` model method has been removed.
|
901
|
+
|
902
|
+
- The `Attacher#read_cached` method has been renamed to
|
903
|
+
`Attacher#cached_data`.
|
904
|
+
|
905
|
+
* `default_url`
|
906
|
+
|
907
|
+
- Passing a block when loading the plugin is not supported anymore.
|
908
|
+
|
909
|
+
* `determine_mime_type`
|
910
|
+
|
911
|
+
- The deprecated `:default` analyzer alias has been removed.
|
912
|
+
|
913
|
+
- The private `Shrine#mime_type_analyzers` method has been removed.
|
914
|
+
|
915
|
+
* `store_dimensions`
|
916
|
+
|
917
|
+
- Failing to extract dimensions now prints out a warning by default.
|
918
|
+
|
919
|
+
- The private `Shrine#extract_dimensions` and `Shrine#dimensions_analyzers`
|
920
|
+
methods have been removed.
|
921
|
+
|
922
|
+
* `infer_extension`
|
923
|
+
|
924
|
+
- The `:mini_mime` inferrer is now the default inferrer, which requires the
|
925
|
+
`mini_mime` gem.
|
926
|
+
|
927
|
+
- The private `Shrine#infer_extension` method has been removed.
|
928
|
+
|
929
|
+
* `validation_helpers`
|
930
|
+
|
931
|
+
- The width & height validators will now raise an exception if `width` or
|
932
|
+
`height` metadata is missing.
|
933
|
+
|
934
|
+
- Support for regexes has been dropped for MIME type and extension
|
935
|
+
validators.
|
936
|
+
|
937
|
+
* `versions`
|
938
|
+
|
939
|
+
- The deprecated `:version_names`, `Shrine.version_names` and
|
940
|
+
`Shrine.version?` have been removed from `versions` plugin.
|
941
|
+
|
942
|
+
* `keep_files`
|
943
|
+
|
944
|
+
- The plugin will now always prevent deletion of both replaced and destroyed
|
945
|
+
attachments. The `:replaced` and `:destroyed` options don't have effect
|
946
|
+
anymore.
|
947
|
+
|
948
|
+
* `dynamic_storage`
|
949
|
+
|
950
|
+
- The `Shrine.dynamic_storages` method has been removed.
|
951
|
+
|
952
|
+
* `instrumentation`
|
953
|
+
|
954
|
+
- The `:location`, `:upload_options`, and `:metadata` keys have been removed
|
955
|
+
from `:options` in `upload.shrine` event payload.
|
956
|
+
|
957
|
+
- The `:metadata` key has been removed from `metadata.shrine` event payload.
|
958
|
+
|
959
|
+
* `default_storage`
|
960
|
+
|
961
|
+
- Passing `record` & `name` arguments to the storage block has been
|
962
|
+
deprecated over evaluating the block in context of the attacher instance.
|
963
|
+
|
964
|
+
* `sequel`
|
965
|
+
|
966
|
+
- The `:callbacks` plugin option has been renamed to `:hooks`.
|
967
|
+
|
968
|
+
[derivatives]: https://shrinerb.com/docs/plugins/derivatives
|
969
|
+
[versions]: https://shrinerb.com/docs/plugins/versions
|
970
|
+
[backgrounding]: https://shrinerb.com/docs/plugins/backgrounding
|
971
|
+
[shrine-memory]: https://github.com/shrinerb/shrine-memory
|
972
|
+
[atomic_helpers]: https://shrinerb.com/docs/plugins/atomic_helpers
|
973
|
+
[attacher]: https://shrinerb.com/docs/attacher
|
974
|
+
[column]: https://shrinerb.com/docs/plugins/column
|
975
|
+
[entity]: https://shrinerb.com/docs/plugins/entity
|
976
|
+
[model]: https://shrinerb.com/docs/plugins/model
|
977
|
+
[persistence]: https://shrinerb.com/docs/plugins/persistence
|
978
|
+
[mirroring]: https://shrinerb.com/docs/plugins/mirroring
|
979
|
+
[form_assign]: https://shrinerb.com/docs/plugins/form_assign
|
980
|
+
[multi_cache]: https://shrinerb.com/docs/plugins/multi_cache
|
981
|
+
[Upgrading to Shrine 3.x]: https://shrinerb.com/docs/upgrading-to-3
|