shrine 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8cfa59ed1f6143ee9298ede17eeda07dba85f0f9c3309a5b7a9e7f6c41399f29
4
- data.tar.gz: 67a64a3a4f40c34797ca04279af73829acf4071eb118f78addefdbaa15e048da
3
+ metadata.gz: 9c012576836f3a56efa91be436999395123342c4650f76f152ef64808ce82ddb
4
+ data.tar.gz: 5be0e63b923ba28f838b4f692758af3eb975c937c4b63453acc629aab0240eac
5
5
  SHA512:
6
- metadata.gz: e87a3dbb80a304f8af559b9c3d4e8badf8e47e4377afd74fe08d570042d65358d44878c4a0366fa3cded98fe166083275e86c61f3b51d28d35e070e0233dea35
7
- data.tar.gz: 83c93e76bf5513ab317ccabbdda86ce90f760e7b898dc9f40036af3e7ec915f48e55bd6f8efcf8661dacea672ce6b24b450db217815b062881169c8c90fd0cd3
6
+ metadata.gz: da5eb6be96c3cacb0575e124b4238c038709d44f33085a5bfb4ae6cb1702d079ba0c7f1ca775828812c6d8cacd1b75aa5979c564dbe0e1ea52fea0036c0f577e
7
+ data.tar.gz: fe12c86f5d826581e4ecb1b5e1951ca1330c8d6d288d19001badd79dab646013a2e57faf51d6cf7369669515636dda3058bf42a2128ea04934f7b611a53e97dd
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## 3.4.0 (2021-06-14)
2
+
3
+ * `base` – Fix passing options to `Shrine.Attachment` on Ruby 3.0 (@lucianghinda)
4
+
5
+ * `determine_mime_type` – Return correct `image/svg+xml` MIME type for SVGs with `:fastimage` analyzer (@Bandes)
6
+
7
+ * `activerecord` – Fix keyword argument warning when adding errors with options (@janko)
8
+
9
+ * `entity` – Make `Attacher#read` method public (@janko)
10
+
11
+ * `entity` – Reset attachment dirty tracking in `Attacher#reload` (@janko)
12
+
13
+ * `activerecord` – Don't load the attacher on `ActiveRecord::Base#reload` if it hasn't yet been initialized (@janko)
14
+
15
+ * `sequel` – Don't load the attacher on `Sequel::Model#reload` if it hasn't yet been initialized (@janko)
16
+
1
17
  ## 3.3.0 (2020-10-04)
2
18
 
3
19
  * `s3` - Support new `Aws::S3::EncryptionV2::Client` for client-side encryption (@janko)
data/README.md CHANGED
@@ -57,8 +57,9 @@ Next, add the `<name>_data` column to the table you want to attach files to. For
57
57
  an "image" attachment on a `photos` table this would be an `image_data` column:
58
58
 
59
59
  ```
60
- $ rails generate migration add_image_data_to_photos image_data:text
60
+ $ rails generate migration add_image_data_to_photos image_data:text # or :jsonb
61
61
  ```
62
+ If using `jsonb` consider adding a [gin index] for fast key-value pair searchability within `image_data`.
62
63
 
63
64
  Now create an uploader class (which you can put in `app/uploaders`) and
64
65
  register the attachment on your model:
@@ -175,3 +176,4 @@ The gem is available as open source under the terms of the [MIT License].
175
176
  [CoC]: /CODE_OF_CONDUCT.md
176
177
  [MIT License]: /LICENSE.txt
177
178
  [Contributing]: https://github.com/shrinerb/shrine/blob/master/CONTRIBUTING.md
179
+ [gin index]: https://www.postgresql.org/docs/current/datatype-json.html#JSON-INDEXING
@@ -212,7 +212,7 @@ Photo.find_each do |photo|
212
212
  next unless attacher.stored?
213
213
 
214
214
  square = attacher.file.download do |original|
215
- ImageProcessor::MiniMagick
215
+ ImageProcessing::MiniMagick
216
216
  .source(original)
217
217
  .resize_to_fill!(150, 150)
218
218
  end
@@ -53,16 +53,17 @@ Photo.find_each do |photo|
53
53
  next unless attacher.stored? # move only attachments uploaded to permanent storage
54
54
 
55
55
  old_attacher = attacher.dup
56
+ current_file = old_attacher.file
56
57
 
57
58
  attacher.set attacher.upload(attacher.file) # reupload file
58
59
  attacher.set_derivatives attacher.upload_derivatives(attacher.derivatives) # reupload derivatives if you have derivatives
59
60
 
60
61
  begin
61
- attacher.atomic_persist # persist changes if attachment has not changed in the meantime
62
- old_attacher.destroy_attached # delete files on old location
63
- rescue Shrine::AttachmentChanged, # attachment has changed during reuploading
64
- ActiveRecord::RecordNotFound # record has been deleted during reuploading
65
- attacher.destroy_attached # delete now orphaned files
62
+ attacher.atomic_persist(current_file) # persist changes if attachment has not changed in the meantime
63
+ old_attacher.destroy_attached # delete files on old location
64
+ rescue Shrine::AttachmentChanged, # attachment has changed during reuploading
65
+ ActiveRecord::RecordNotFound # record has been deleted during reuploading
66
+ attacher.destroy_attached # delete now orphaned files
66
67
  end
67
68
  end
68
69
  ```
data/doc/design.md CHANGED
@@ -9,11 +9,11 @@ There are five main types of classes that you deal with in Shrine:
9
9
 
10
10
  | Class | Description |
11
11
  | :---- | :---------- |
12
- | `Shrine::Storage::*` | Manages files on a particular storage service |
13
- | `Shrine` | Wraps uploads and handles loading plugins |
14
- | `Shrine::UploadedFile` | Represents a file uploaded to a storage |
15
- | `Shrine::Attacher` | Handles file attachment logic |
16
- | `Shrine::Attachment` | Provides convenience model attachment interface |
12
+ | [`Shrine::Storage::*`](#Storage) | Manages files on a particular storage service |
13
+ | [`Shrine`](#Shrine) | Wraps uploads and handles loading plugins |
14
+ | [`Shrine::UploadedFile`](#shrineuploadedfile) | Represents a file uploaded to a storage |
15
+ | [`Shrine::Attacher`](#shrineattacher) | Handles file attachment logic |
16
+ | [`Shrine::Attachment`](#shrineattachment) | Provides convenience model attachment interface |
17
17
 
18
18
  ## Storage
19
19
 
data/doc/direct_s3.md CHANGED
@@ -86,6 +86,31 @@ If you're using [Uppy], this is the recommended CORS configuration for the
86
86
  </CORSConfiguration>
87
87
  ```
88
88
 
89
+ Or in JSON format:
90
+
91
+ ```json
92
+ [
93
+ {
94
+ "AllowedOrigins": [ "https://my-app.com" ],
95
+ "AllowedMethods": [ "GET", "POST", "PUT" ],
96
+ "MaxAgeSeconds": 3000,
97
+ "AllowedHeaders": [
98
+ "Authorization",
99
+ "x-amz-date",
100
+ "x-amz-content-sha256",
101
+ "Content-Type",
102
+ "Content-Disposition"
103
+ ],
104
+ "ExposeHeaders": [ "ETag" ]
105
+ },
106
+ {
107
+ "AllowedOrigins": [ "*" ],
108
+ "AllowedMethods": [ "GET" ],
109
+ "MaxAgeSeconds": 3000
110
+ }
111
+ ]
112
+ ```
113
+
89
114
  Replace `https://my-app.com` with the URL to your app (in development you can
90
115
  set this to `*`). Once you've hit "Save", it may take some time for the
91
116
  new CORS settings to be applied.
@@ -37,22 +37,26 @@ will use to store all information about the attachment:
37
37
  ```rb
38
38
  Sequel.migration do
39
39
  change do
40
- add_column :photos, :image_data, :text # or :jsonb
40
+ add_column :photos, :image_data, :text # or :jsonb
41
41
  end
42
42
  end
43
43
  ```
44
+
44
45
  <!--ActiveRecord-->
45
46
  ```rb
46
47
  class AddImageDataToPhotos < ActiveRecord::Migration
47
48
  def change
48
- add_column :photos, :image_data, :text # or :jsonb
49
+ add_column :photos, :image_data, :text # or :jsonb
49
50
  end
50
51
  end
51
52
  ```
53
+
52
54
  <!--Rails-->
55
+ ```rb
56
+ $ rails generate migration add_image_data_to_photos image_data:text # or image_data:jsonb
53
57
  ```
54
- $ rails generate migration add_image_data_to_photos image_data:text
55
- ```
58
+ If using `jsonb` consider adding a [gin index] for fast key-value pair searchability within `image_data`.
59
+
56
60
  <!--END_DOCUSAURUS_CODE_TABS-->
57
61
 
58
62
  Now you can create an uploader class for the type of files you want to upload,
@@ -481,6 +485,12 @@ If you want to extend Shrine functionality with custom behaviour, you can also
481
485
  [create your own plugin][Creating Plugins]. There are also additional [external
482
486
  plugins] created by others.
483
487
 
488
+ > NOTE: An uploader class will inherit a copy of current superclass' plugin
489
+ > options at the time of subclassing. This means you should *not* load
490
+ > additional plugins on a superclass after the subclass has already been
491
+ > created, because new options will not get applied to the subclass, which
492
+ > can result in errors.
493
+
484
494
  ## Metadata
485
495
 
486
496
  Shrine automatically extracts some basic file metadata and saves them to the
@@ -531,7 +541,7 @@ the [Extracting Metadata] guide for more details.
531
541
 
532
542
  Shrine allows you to process attached files both "eagerly" and "on-the-fly".
533
543
  For example, if your app is accepting image uploads, you can generate a
534
- predefined set of of thumbnails when the image is attached to a record, or you
544
+ predefined set of thumbnails when the image is attached to a record, or you
535
545
  can have thumbnails generated dynamically as they're needed.
536
546
 
537
547
  For image processing, it's recommended to use the **[ImageProcessing]** gem,
@@ -1102,3 +1112,4 @@ Shrine.logger.level = Logger::WARN
1102
1112
  [storages]: https://shrinerb.com/docs/external/extensions#storages
1103
1113
  [plugins]: https://shrinerb.com/plugins
1104
1114
  [external plugins]: https://shrinerb.com/docs/external/extensions#plugins
1115
+ [gin index]: https://www.postgresql.org/docs/current/datatype-json.html#JSON-INDEXING
data/doc/metadata.md CHANGED
@@ -175,7 +175,7 @@ uploaded_file.exif #=> {...}
175
175
  ```
176
176
 
177
177
  Or, if you're uploading videos, you might want to extract some video-specific
178
- meatadata:
178
+ metadata:
179
179
 
180
180
  ```rb
181
181
  # Gemfile
data/doc/paperclip.md CHANGED
@@ -695,6 +695,7 @@ s3.upload(io, "object/destination/path")
695
695
  The Shrine storage has no replacement for the `:url` Paperclip option, and it
696
696
  isn't needed.
697
697
 
698
+ [metadata_attributes]: https://shrinerb.com/docs/plugins/metadata_attributes
698
699
  [Managing Derivatives]: https://shrinerb.com/docs/changing-derivatives
699
700
  [direct uploads]: https://shrinerb.com/docs/getting-started#direct-uploads
700
701
  [S3]: https://shrinerb.com/docs/storage/s3
@@ -22,7 +22,9 @@ These methods read attachment data from the `#<name>_data` attribute on the
22
22
  entity instance.
23
23
 
24
24
  ```rb
25
- class Photo < Entity(:image_data) # has `image_data` reader
25
+ class Photo
26
+ attr_reader :image_data
27
+
26
28
  include ImageUploader::Attachment(:image)
27
29
  end
28
30
  ```
@@ -94,7 +96,9 @@ You can also specify default attacher options when including
94
96
  `Shrine::Attachment`:
95
97
 
96
98
  ```rb
97
- class Photo < Entity(:image_data)
99
+ class Photo
100
+ attr_reader :image_data
101
+
98
102
  include ImageUploader::Attachment(:image, store: :other_store)
99
103
  end
100
104
  ```
@@ -123,7 +127,8 @@ You can also use `Shrine::Attacher` directly (with or without the
123
127
  `Shrine::Attachment` module):
124
128
 
125
129
  ```rb
126
- class Photo < Entity(:image_data) # has `image_data` reader
130
+ class Photo
131
+ attr_reader :image_data
127
132
  end
128
133
  ```
129
134
  ```rb
@@ -191,7 +196,7 @@ attacher.file #=> nil
191
196
  ### Reloading
192
197
 
193
198
  The `Attacher#reload` method reloads attached file from the attachment data on
194
- the entity attribute.
199
+ the entity attribute and resets dirty tracking.
195
200
 
196
201
  ```rb
197
202
  photo = Photo.new
@@ -206,6 +211,9 @@ attacher.reload
206
211
  attacher.file #=> #<ImageUploader::UploadedFile>
207
212
  ```
208
213
 
214
+ If you want to reload attachment data while retaining dirty tracking state, use
215
+ `Attacher#read` instead.
216
+
209
217
  ### Column values
210
218
 
211
219
  The `Attacher#column_values` method returns a hash with the entity attribute as
@@ -173,7 +173,7 @@ methods:
173
173
 
174
174
  ```rb
175
175
  # sends a `my_event.shrine` event to the notifications component
176
- Shrine.instrument(:my_event, foo: "bar") do
176
+ Shrine.instrument(:my_event, { foo: "bar" }) do
177
177
  # do work
178
178
  end
179
179
  ```
data/doc/plugins/model.md CHANGED
@@ -17,7 +17,9 @@ Including a `Shrine::Attachment` module into a model class will:
17
17
  * add `#<name>=` and `#<name>_changed?` methods
18
18
 
19
19
  ```rb
20
- class Photo < Model(:image_data) # has `image_data` accessor
20
+ class Photo
21
+ attr_accessor :image_data
22
+
21
23
  include ImageUploader::Attachment(:image)
22
24
  end
23
25
  ```
@@ -107,7 +109,9 @@ If you still want to include `Shrine::Attachment` modules to immutable
107
109
  entities, you can disable "model" behaviour by passing `model: false`:
108
110
 
109
111
  ```rb
110
- class Photo < Entity(:image_data)
112
+ class Photo
113
+ attr_reader :image_data
114
+
111
115
  include ImageUploader::Attachment(:image, model: false)
112
116
  end
113
117
  ```
@@ -118,7 +122,8 @@ You can also use `Shrine::Attacher` directly (with or without the
118
122
  `Shrine::Attachment` module):
119
123
 
120
124
  ```rb
121
- class Photo < Model(:image_data) # has `image_data` accessor
125
+ class Photo
126
+ attr_accessor :image_data
122
127
  end
123
128
  ```
124
129
  ```rb
@@ -172,7 +172,7 @@ attacher.file #=> #<Shrine::UploadedFile id="397eca.jpg" storage=:store ...>
172
172
  photo.image_data #=> '{"id":"397eca.jpg","storage":"store","metadata":{...}}'
173
173
  ```
174
174
 
175
- ### Pesistence
175
+ ### Persistence
176
176
 
177
177
  The following persistence methods are added to `Shrine::Attacher`:
178
178
 
data/doc/processing.md CHANGED
@@ -315,14 +315,15 @@ previews.
315
315
 
316
316
  Shrine provides on-the-fly processing functionality via the
317
317
  **[`derivation_endpoint`][derivation_endpoint]** plugin. You set it up by
318
- loading the plugin with a secret key and a path prefix, mount its Rack app in
318
+ loading the plugin with a secret key (you generate this yourself, maybe via
319
+ something like `SecureRandom.hex`) and a path prefix, mount its Rack app in
319
320
  your routes on the configured path prefix, and define processing you want to
320
321
  perform:
321
322
 
322
323
  ```rb
323
324
  # config/initializers/shrine.rb (Rails)
324
325
  # ...
325
- Shrine.plugin :derivation_endpoints, secret_key: "<YOUR_SECRET_KEY>"
326
+ Shrine.plugin :derivation_endpoint, secret_key: "<SHRINE_SECRET_KEY>"
326
327
  ```
327
328
  ```rb
328
329
  require "image_processing/mini_magick"
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: Shrine 3.4.0
3
+ ---
4
+
5
+ * Passing attacher options to `Shrine.Attachment` method now works on Ruby 3.0.
6
+
7
+ * Defining validation errors as an array of I18n key and options in
8
+ `activerecord` plugin now works on Ruby 3.0.
9
+
10
+ * The `:fastimage` MIME type analyzer now correctly detects SVGs as
11
+ `image/svg+html` in the `determine_mime_type` plugin.
12
+
13
+ * The `Shrine::Attacher#read` method provided by the `entity` plugin is now
14
+ public. This is consistent with `Shrine::Attacher#write` from `model` plugin
15
+ being public as well.
16
+
17
+ * The `Shrine::Attacher#reload` method now resets attachment's dirty state.
18
+ This means that for a model whose `Attacher#changed?` returns `true`, calling
19
+ `#reload` on the model will make `Attacher#changed?` return `false`. This was
20
+ the behaviour before Shrine 3.3.0.
21
+
22
+ ```rb
23
+ # before
24
+ model.file_attacher.changed? #=> true
25
+ model.reload
26
+ model.file_attacher.changed? #=> true
27
+
28
+ # after
29
+ model.file_attacher.changed? #=> true
30
+ model.reload
31
+ model.file_attacher.changed? #=> false
32
+ ```
33
+
34
+ * Calling `#reload` on the model will not initialize a `Shrine::Attacher`
35
+ instance anymore if one hasn't previously been initialized.
data/doc/testing.md CHANGED
@@ -251,6 +251,16 @@ TestMode.disable_processing(Photo.image_attacher) do
251
251
  end
252
252
  ```
253
253
 
254
+ ## Testing direct upload
255
+
256
+ If you'd like to unit-test direct upload on the server side, you can
257
+ emulate it by uploading a file to `cache` and then assigning it to the record.
258
+
259
+ ```rb
260
+ cached_file = Shrine.upload(some_file, :cache)
261
+ record.attachment = cached_file.to_json
262
+ ```
263
+
254
264
  [DatabaseCleaner]: https://github.com/DatabaseCleaner/database_cleaner
255
265
  [`#attach_file`]: http://www.rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions#attach_file-instance_method
256
266
  [aws-sdk-ruby stubs]: http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/ClientStubs.html
@@ -237,7 +237,7 @@ class PromoteJob
237
237
  rescue Shrine::AttachmentChanged, ActiveRecord::RecordNotFound
238
238
  # attachment has changed or record has been deleted, nothing to do
239
239
  end
240
- and
240
+ end
241
241
  ```
242
242
  ```rb
243
243
  class DestroyJob
@@ -258,7 +258,7 @@ class DestroyJob
258
258
  attacher = attacher_class.from_data(data)
259
259
  attacher.destroy
260
260
  end
261
- and
261
+ end
262
262
  ```
263
263
 
264
264
  ### Attacher backgrounding
@@ -439,7 +439,7 @@ creation in the `PromoteJob` instead of the controller:
439
439
  class PromoteJob
440
440
  include Sidekiq::Worker
441
441
 
442
- def perform(attacher_class, record_class, record.id, name, file_data)
442
+ def perform(attacher_class, record_class, record_id, name, file_data)
443
443
  attacher_class = Object.const_get(attacher_class)
444
444
  record = Object.const_get(record_class).find(record_id) # if using Active Record
445
445
 
data/lib/shrine.rb CHANGED
@@ -95,8 +95,8 @@ class Shrine
95
95
  # class Photo
96
96
  # include Shrine::Attachment(:image) # creates a Shrine::Attachment object
97
97
  # end
98
- def Attachment(name, *args)
99
- self::Attachment.new(name, *args)
98
+ def Attachment(name, **args)
99
+ self::Attachment.new(name, **args)
100
100
  end
101
101
  alias attachment Attachment
102
102
  alias [] Attachment
@@ -55,7 +55,7 @@ class Shrine
55
55
  # reload the attacher on record reload
56
56
  define_method :reload do |*args|
57
57
  result = super(*args)
58
- send(:"#{name}_attacher").reload
58
+ send(:"#{name}_attacher").reload if instance_variable_defined?(:"@#{name}_attacher")
59
59
  result
60
60
  end
61
61
  end
@@ -75,8 +75,8 @@ class Shrine
75
75
  def activerecord_validate
76
76
  return unless respond_to?(:errors)
77
77
 
78
- errors.each do |message|
79
- record.errors.add(name, *message)
78
+ errors.each do |(type, options)|
79
+ record.errors.add(name, type, **options.to_h)
80
80
  end
81
81
  end
82
82
 
@@ -603,7 +603,7 @@ class Shrine
603
603
  def instrument_derivation(&block)
604
604
  return yield unless shrine_class.respond_to?(:instrument)
605
605
 
606
- shrine_class.instrument(:derivation, derivation: derivation, &block)
606
+ shrine_class.instrument(:derivation, { derivation: derivation }, &block)
607
607
  end
608
608
 
609
609
  # Massages the derivation result, ensuring it's opened in binary mode,
@@ -507,14 +507,12 @@ class Shrine
507
507
  def instrument_derivatives(processor_name, source, processor_options, &block)
508
508
  return yield unless shrine_class.respond_to?(:instrument)
509
509
 
510
- shrine_class.instrument(
511
- :derivatives,
510
+ shrine_class.instrument(:derivatives, {
512
511
  processor: processor_name,
513
512
  processor_options: processor_options,
514
513
  io: source,
515
514
  attacher: self,
516
- &block
517
- )
515
+ }, &block)
518
516
  end
519
517
 
520
518
  # Returns symbolized array or single key.
@@ -124,6 +124,8 @@ class Shrine
124
124
  require "fastimage"
125
125
 
126
126
  type = FastImage.type(io)
127
+ return 'image/svg+xml' if type == :svg
128
+
127
129
  "image/#{type}" if type
128
130
  end
129
131
 
@@ -112,9 +112,15 @@ class Shrine
112
112
  # attacher.file #=> #<Shrine::UploadedFile>
113
113
  def reload
114
114
  read
115
+ @previous = nil
115
116
  self
116
117
  end
117
118
 
119
+ # Loads attachment from the entity attribute.
120
+ def read
121
+ load_column(read_attribute)
122
+ end
123
+
118
124
  # Returns a hash with entity attribute name and column data.
119
125
  #
120
126
  # attacher.column_values
@@ -134,11 +140,6 @@ class Shrine
134
140
 
135
141
  private
136
142
 
137
- # Loads attachment from the entity attribute.
138
- def read
139
- load_column(read_attribute)
140
- end
141
-
142
143
  # Reads value from the entity attribute.
143
144
  def read_attribute
144
145
  record.public_send(attribute)
@@ -69,27 +69,25 @@ class Shrine
69
69
 
70
70
  # Sends a `upload.shrine` event.
71
71
  def _upload(io, location:, metadata:, upload_options: {}, **options)
72
- self.class.instrument(
73
- :upload,
72
+ self.class.instrument(:upload, {
74
73
  storage: storage_key,
75
74
  location: location,
76
75
  io: io,
77
76
  upload_options: upload_options,
78
77
  metadata: metadata,
79
78
  options: options,
80
- ) { super }
79
+ }) { super }
81
80
  end
82
81
 
83
82
  # Sends a `metadata.shrine` event.
84
83
  def get_metadata(io, metadata: nil, **options)
85
84
  return super if io.is_a?(UploadedFile) && metadata != true || metadata == false
86
85
 
87
- self.class.instrument(
88
- :metadata,
86
+ self.class.instrument(:metadata, {
89
87
  storage: storage_key,
90
88
  io: io,
91
89
  options: options,
92
- ) { super }
90
+ }) { super }
93
91
  end
94
92
  end
95
93
 
@@ -98,30 +96,27 @@ class Shrine
98
96
  def stream(destination, **options)
99
97
  return super if opened?
100
98
 
101
- shrine_class.instrument(
102
- :download,
99
+ shrine_class.instrument(:download, {
103
100
  storage: storage_key,
104
101
  location: id,
105
102
  download_options: options,
106
- ) { super(destination, **options, instrument: false) }
103
+ }) { super(destination, **options, instrument: false) }
107
104
  end
108
105
 
109
106
  # Sends a `exists.shrine` event.
110
107
  def exists?
111
- shrine_class.instrument(
112
- :exists,
108
+ shrine_class.instrument(:exists, {
113
109
  storage: storage_key,
114
110
  location: id,
115
- ) { super }
111
+ }) { super }
116
112
  end
117
113
 
118
114
  # Sends a `delete.shrine` event.
119
115
  def delete
120
- shrine_class.instrument(
121
- :delete,
116
+ shrine_class.instrument(:delete, {
122
117
  storage: storage_key,
123
118
  location: id,
124
- ) { super }
119
+ }) { super }
125
120
  end
126
121
 
127
122
  private
@@ -130,12 +125,11 @@ class Shrine
130
125
  def _open(instrument: true, **options)
131
126
  return super(**options) unless instrument
132
127
 
133
- shrine_class.instrument(
134
- :open,
128
+ shrine_class.instrument(:open, {
135
129
  storage: storage_key,
136
130
  location: id,
137
131
  download_options: options,
138
- ) { super(**options) }
132
+ }) { super(**options) }
139
133
  end
140
134
  end
141
135
 
@@ -62,7 +62,7 @@ class Shrine
62
62
  # reload the attacher on record reload
63
63
  define_method :_refresh do |*args|
64
64
  result = super(*args)
65
- send(:"#{name}_attacher").reload
65
+ send(:"#{name}_attacher").reload if instance_variable_defined?(:"@#{name}_attacher")
66
66
  result
67
67
  end
68
68
  private :_refresh
@@ -7,7 +7,7 @@ class Shrine
7
7
 
8
8
  module VERSION
9
9
  MAJOR = 3
10
- MINOR = 3
10
+ MINOR = 4
11
11
  TINY = 0
12
12
  PRE = nil
13
13
 
data/shrine.gemspec CHANGED
@@ -63,6 +63,7 @@ direct uploads for fully asynchronous user experience.
63
63
  # for S3 storage
64
64
  gem.add_development_dependency "aws-sdk-s3", "~> 1.69"
65
65
  gem.add_development_dependency "aws-sdk-core", "~> 3.23"
66
+ gem.add_development_dependency "rexml"
66
67
 
67
68
  # for instrumentation plugin
68
69
  gem.add_development_dependency "dry-monitor"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shrine
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janko Marohnić
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-04 00:00:00.000000000 Z
11
+ date: 2021-06-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: down
@@ -262,6 +262,20 @@ dependencies:
262
262
  - - "~>"
263
263
  - !ruby/object:Gem::Version
264
264
  version: '3.23'
265
+ - !ruby/object:Gem::Dependency
266
+ name: rexml
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - ">="
270
+ - !ruby/object:Gem::Version
271
+ version: '0'
272
+ type: :development
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - ">="
277
+ - !ruby/object:Gem::Version
278
+ version: '0'
265
279
  - !ruby/object:Gem::Dependency
266
280
  name: dry-monitor
267
281
  requirement: !ruby/object:Gem::Requirement
@@ -459,6 +473,7 @@ files:
459
473
  - doc/release_notes/3.2.1.md
460
474
  - doc/release_notes/3.2.2.md
461
475
  - doc/release_notes/3.3.0.md
476
+ - doc/release_notes/3.4.0.md
462
477
  - doc/retrieving_uploads.md
463
478
  - doc/securing_uploads.md
464
479
  - doc/storage/file_system.md
@@ -538,7 +553,7 @@ metadata:
538
553
  documentation_uri: https://shrinerb.com
539
554
  mailing_list_uri: https://discourse.shrinerb.com
540
555
  source_code_uri: https://github.com/shrinerb/shrine
541
- post_install_message:
556
+ post_install_message:
542
557
  rdoc_options: []
543
558
  require_paths:
544
559
  - lib
@@ -553,8 +568,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
553
568
  - !ruby/object:Gem::Version
554
569
  version: '0'
555
570
  requirements: []
556
- rubygems_version: 3.1.4
557
- signing_key:
571
+ rubygems_version: 3.2.15
572
+ signing_key:
558
573
  specification_version: 4
559
574
  summary: Toolkit for file attachments in Ruby applications
560
575
  test_files: []