shrine 3.3.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []