shrine 3.0.0 → 3.2.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of shrine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +87 -33
- data/LICENSE.txt +1 -1
- data/README.md +94 -4
- data/doc/advantages.md +35 -18
- data/doc/attacher.md +16 -17
- data/doc/carrierwave.md +75 -34
- data/doc/changing_derivatives.md +39 -39
- data/doc/design.md +134 -85
- data/doc/external/articles.md +56 -41
- data/doc/external/extensions.md +38 -34
- data/doc/getting_started.md +182 -112
- data/doc/metadata.md +79 -43
- data/doc/multiple_files.md +5 -3
- data/doc/paperclip.md +110 -42
- data/doc/plugins/activerecord.md +5 -5
- data/doc/plugins/add_metadata.md +92 -35
- data/doc/plugins/backgrounding.md +12 -2
- data/doc/plugins/column.md +36 -7
- data/doc/plugins/data_uri.md +2 -2
- data/doc/plugins/default_url.md +6 -3
- data/doc/plugins/derivation_endpoint.md +26 -28
- data/doc/plugins/derivatives.md +205 -169
- data/doc/plugins/determine_mime_type.md +2 -2
- data/doc/plugins/entity.md +3 -3
- data/doc/plugins/form_assign.md +5 -5
- data/doc/plugins/included.md +25 -5
- data/doc/plugins/infer_extension.md +2 -2
- data/doc/plugins/instrumentation.md +1 -1
- data/doc/plugins/metadata_attributes.md +21 -10
- data/doc/plugins/model.md +4 -4
- data/doc/plugins/persistence.md +1 -0
- data/doc/plugins/refresh_metadata.md +5 -4
- data/doc/plugins/remote_url.md +8 -3
- data/doc/plugins/remove_invalid.md +9 -1
- data/doc/plugins/sequel.md +4 -4
- data/doc/plugins/signature.md +11 -2
- data/doc/plugins/store_dimensions.md +2 -2
- data/doc/plugins/type_predicates.md +96 -0
- data/doc/plugins/upload_endpoint.md +7 -11
- data/doc/plugins/upload_options.md +1 -1
- data/doc/plugins/url_options.md +2 -2
- data/doc/plugins/validation.md +14 -4
- data/doc/plugins/validation_helpers.md +3 -3
- data/doc/plugins/versions.md +11 -11
- data/doc/processing.md +289 -125
- data/doc/refile.md +39 -18
- data/doc/release_notes/2.19.0.md +1 -1
- data/doc/release_notes/3.0.0.md +275 -258
- 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 +32 -0
- data/doc/release_notes/3.2.2.md +14 -0
- data/doc/securing_uploads.md +3 -3
- data/doc/storage/file_system.md +1 -1
- data/doc/storage/memory.md +19 -0
- data/doc/storage/s3.md +105 -86
- data/doc/testing.md +2 -2
- data/doc/upgrading_to_3.md +115 -33
- data/doc/validation.md +3 -2
- data/lib/shrine.rb +8 -8
- data/lib/shrine/attacher.rb +19 -14
- data/lib/shrine/attachment.rb +5 -5
- data/lib/shrine/plugins.rb +22 -0
- data/lib/shrine/plugins/add_metadata.rb +12 -3
- data/lib/shrine/plugins/default_storage.rb +6 -6
- data/lib/shrine/plugins/default_url.rb +1 -1
- data/lib/shrine/plugins/derivation_endpoint.rb +10 -6
- data/lib/shrine/plugins/derivatives.rb +19 -17
- data/lib/shrine/plugins/determine_mime_type.rb +3 -3
- data/lib/shrine/plugins/entity.rb +6 -6
- data/lib/shrine/plugins/metadata_attributes.rb +1 -1
- data/lib/shrine/plugins/model.rb +3 -3
- data/lib/shrine/plugins/presign_endpoint.rb +2 -2
- data/lib/shrine/plugins/pretty_location.rb +1 -1
- data/lib/shrine/plugins/processing.rb +1 -1
- data/lib/shrine/plugins/refresh_metadata.rb +2 -2
- data/lib/shrine/plugins/remote_url.rb +3 -3
- data/lib/shrine/plugins/remove_invalid.rb +10 -5
- data/lib/shrine/plugins/signature.rb +7 -6
- data/lib/shrine/plugins/store_dimensions.rb +18 -9
- data/lib/shrine/plugins/type_predicates.rb +113 -0
- data/lib/shrine/plugins/upload_endpoint.rb +3 -3
- data/lib/shrine/plugins/upload_options.rb +2 -2
- data/lib/shrine/plugins/url_options.rb +2 -2
- data/lib/shrine/plugins/validation.rb +9 -7
- data/lib/shrine/storage/linter.rb +4 -4
- data/lib/shrine/storage/s3.rb +62 -38
- data/lib/shrine/uploaded_file.rb +5 -1
- data/lib/shrine/version.rb +2 -2
- data/shrine.gemspec +6 -7
- metadata +23 -29
data/doc/testing.md
CHANGED
@@ -119,7 +119,7 @@ module TestData
|
|
119
119
|
small: uploaded_image,
|
120
120
|
)
|
121
121
|
|
122
|
-
attacher.column_data
|
122
|
+
attacher.column_data # or attacher.data in case of postgres jsonb column
|
123
123
|
end
|
124
124
|
|
125
125
|
def uploaded_image
|
@@ -128,7 +128,7 @@ module TestData
|
|
128
128
|
# for performance we skip metadata extraction and assign test metadata
|
129
129
|
uploaded_file = Shrine.upload(file, :store, metadata: false)
|
130
130
|
uploaded_file.metadata.merge!(
|
131
|
-
"size" => file.
|
131
|
+
"size" => File.size(file.path),
|
132
132
|
"mime_type" => "image/jpeg",
|
133
133
|
"filename" => "test.jpg",
|
134
134
|
)
|
data/doc/upgrading_to_3.md
CHANGED
@@ -4,7 +4,11 @@ title: Upgrading to Shrine 3.x
|
|
4
4
|
---
|
5
5
|
|
6
6
|
This guide provides instructions for upgrading Shrine in your apps to version
|
7
|
-
3.x. If you're looking for a full list of changes, see the [3.0 release
|
7
|
+
3.x. If you're looking for a full list of changes, see the **[3.0 release
|
8
|
+
notes]**.
|
9
|
+
|
10
|
+
If you would like assistance with the upgrade, I'm available for consultation,
|
11
|
+
you can email me at <janko.marohnic@gmail.com>.
|
8
12
|
|
9
13
|
## Attacher
|
10
14
|
|
@@ -72,6 +76,20 @@ attacher.reload
|
|
72
76
|
attacher.file #=> #<Shrine::UploadedFile ...>
|
73
77
|
```
|
74
78
|
|
79
|
+
### Assigning
|
80
|
+
|
81
|
+
The `Attacher#assign` method now raises an exception when non-cached uploaded
|
82
|
+
file data is assigned:
|
83
|
+
|
84
|
+
```rb
|
85
|
+
# Shrine 2.x
|
86
|
+
attacher.assign('{"id": "...", "storage": "store", "metadata": {...}}') # ignored
|
87
|
+
|
88
|
+
# Shrine 3.0
|
89
|
+
attacher.assign('{"id": "...", "storage": "store", "metadata": {...}}')
|
90
|
+
#~> Shrine::Error: expected cached file, got #<Shrine::UploadedFile storage=:store ...>
|
91
|
+
```
|
92
|
+
|
75
93
|
### Validation
|
76
94
|
|
77
95
|
The validation functionality has been extracted into the `validation` plugin.
|
@@ -265,8 +283,9 @@ attacher.destroy_background # calls destroy block
|
|
265
283
|
## Versions
|
266
284
|
|
267
285
|
The `versions`, `processing`, `recache`, and `delete_raw` plugins have been
|
268
|
-
deprecated in favour of the new [`derivatives`][derivatives] plugin.
|
269
|
-
|
286
|
+
deprecated in favour of the new **[`derivatives`][derivatives]** plugin.
|
287
|
+
|
288
|
+
Let's assume you have the following `versions` configuration:
|
270
289
|
|
271
290
|
```rb
|
272
291
|
class ImageUploader < Shrine
|
@@ -289,18 +308,23 @@ class ImageUploader < Shrine
|
|
289
308
|
end
|
290
309
|
end
|
291
310
|
```
|
311
|
+
|
312
|
+
When an attached file is promoted to permanent storage, the versions would
|
313
|
+
automatically get generated:
|
314
|
+
|
292
315
|
```rb
|
293
316
|
photo = Photo.new(photo_params)
|
294
317
|
|
295
318
|
if photo.valid?
|
296
|
-
photo.save #
|
319
|
+
photo.save # generates versions on promotion
|
297
320
|
# ...
|
298
321
|
else
|
299
322
|
# ...
|
300
323
|
end
|
301
324
|
```
|
302
325
|
|
303
|
-
With `derivatives
|
326
|
+
With `derivatives`, the original file is automatically downloaded and retained,
|
327
|
+
so the processing code is much simpler:
|
304
328
|
|
305
329
|
```rb
|
306
330
|
Shrine.plugin :derivatives, versions_compatibility: true # handle versions column format
|
@@ -310,6 +334,7 @@ class ImageUploader < Shrine
|
|
310
334
|
Attacher.derivatives_processor do |original|
|
311
335
|
magick = ImageProcessing::MiniMagick.source(original)
|
312
336
|
|
337
|
+
# the :original file should NOT be included anymore
|
313
338
|
{
|
314
339
|
large: magick.resize_to_limit!(800, 800),
|
315
340
|
medium: magick.resize_to_limit!(500, 500),
|
@@ -318,22 +343,25 @@ class ImageUploader < Shrine
|
|
318
343
|
end
|
319
344
|
end
|
320
345
|
```
|
346
|
+
|
347
|
+
However, you now need to trigger processing manually during attachment:
|
348
|
+
|
321
349
|
```rb
|
322
350
|
photo = Photo.new(photo_params)
|
323
351
|
|
324
352
|
if photo.valid?
|
325
353
|
photo.image_derivatives! if photo.image_changed? # create derivatives
|
326
|
-
photo.save
|
354
|
+
photo.save
|
327
355
|
# ...
|
328
356
|
else
|
329
357
|
# ...
|
330
358
|
end
|
331
359
|
```
|
332
360
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
361
|
+
### Automatic processing
|
362
|
+
|
363
|
+
If you prefer processing to happen automatically with promotion (like it did
|
364
|
+
with the `versions` plugin), you can put the following in your initializer:
|
337
365
|
|
338
366
|
```rb
|
339
367
|
class Shrine::Attacher
|
@@ -352,7 +380,7 @@ The derivative URLs are accessed in the same way as versions:
|
|
352
380
|
photo.image_url(:small)
|
353
381
|
```
|
354
382
|
|
355
|
-
But the
|
383
|
+
But the files themselves are accessed differently:
|
356
384
|
|
357
385
|
```rb
|
358
386
|
# versions
|
@@ -406,8 +434,8 @@ database column in different formats:
|
|
406
434
|
|
407
435
|
The `:versions_compatibility` flag to the `derivatives` plugin enables it to
|
408
436
|
read the `versions` format, which aids in transition. Once the `derivatives`
|
409
|
-
plugin has been deployed to production, you can
|
410
|
-
new column format:
|
437
|
+
plugin has been deployed to production, you can update existing records with
|
438
|
+
the new column format:
|
411
439
|
|
412
440
|
```rb
|
413
441
|
Photo.find_each do |photo|
|
@@ -468,48 +496,77 @@ else
|
|
468
496
|
end
|
469
497
|
```
|
470
498
|
|
471
|
-
|
499
|
+
### Default URL
|
472
500
|
|
473
|
-
|
474
|
-
|
501
|
+
If you were using the `default_url` plugin, the `Attacher.default_url` now
|
502
|
+
receives a `:derivative` option:
|
475
503
|
|
476
504
|
```rb
|
477
|
-
|
478
|
-
|
505
|
+
Attacher.default_url do |derivative: nil, **|
|
506
|
+
"https://my-app.com/fallbacks/#{derivative}.jpg" if derivative
|
507
|
+
end
|
479
508
|
```
|
480
|
-
```rb
|
481
|
-
require "concurrent"
|
482
509
|
|
483
|
-
|
510
|
+
#### Fallback to original
|
484
511
|
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
end
|
489
|
-
end
|
512
|
+
With the `versions` plugin, a missing version URL would automatically fall back
|
513
|
+
to the original file. The `derivatives` plugin has no such fallback, but you
|
514
|
+
can configure it manually:
|
490
515
|
|
491
|
-
|
516
|
+
```rb
|
517
|
+
Attacher.default_url do |derivative: nil, **|
|
518
|
+
file&.url if derivative
|
519
|
+
end
|
492
520
|
```
|
493
521
|
|
494
|
-
####
|
522
|
+
#### Fallback to version
|
495
523
|
|
496
|
-
The `
|
524
|
+
The `versions` plugin had the ability to fall back missing version URL to
|
525
|
+
another version that already exists. The `derivatives` plugin doesn't have this
|
526
|
+
built in, but you can implement it as follows:
|
497
527
|
|
498
528
|
```rb
|
529
|
+
DERIVATIVE_FALLBACKS = { foo: :bar, ... }
|
530
|
+
|
499
531
|
Attacher.default_url do |derivative: nil, **|
|
500
|
-
|
532
|
+
derivatives[DERIVATIVE_FALLBACKS[derivative]]&.url if derivative
|
501
533
|
end
|
502
534
|
```
|
503
535
|
|
504
|
-
|
505
|
-
|
536
|
+
### Location
|
537
|
+
|
538
|
+
The `Shrine#generate_location` method will now receive a `:derivative`
|
539
|
+
parameter instead of `:version`:
|
540
|
+
|
541
|
+
```rb
|
542
|
+
class MyUploader < Shrine
|
543
|
+
def generate_location(io, derivative: nil, **)
|
544
|
+
derivative #=> :large, :medium, :small, ...
|
545
|
+
# ...
|
546
|
+
end
|
547
|
+
end
|
548
|
+
```
|
549
|
+
|
550
|
+
### Overwriting original
|
551
|
+
|
552
|
+
With the `derivatives` plugin, saving processed files separately from the
|
553
|
+
original file, so the original file is automatically kept. This means it's not
|
554
|
+
possible anymore to overwrite the original file as part of processing.
|
555
|
+
|
556
|
+
However, **it's highly recommended to always keep the original file**, even if
|
557
|
+
you don't plan to use it. That way, if there is ever a need to reprocess
|
558
|
+
derivatives, you have the original file to use as a base.
|
559
|
+
|
560
|
+
That being said, if you still want to overwrite the original file, [this
|
561
|
+
thread][overwriting original] has some tips.
|
506
562
|
|
507
563
|
## Other
|
508
564
|
|
509
565
|
### Processing
|
510
566
|
|
511
567
|
The `processing` plugin has been deprecated over the new
|
512
|
-
[`derivatives`][derivatives] plugin. If you were
|
568
|
+
[`derivatives`][derivatives] plugin. If you were previously replacing the
|
569
|
+
original file:
|
513
570
|
|
514
571
|
```rb
|
515
572
|
class MyUploader < Shrine
|
@@ -537,6 +594,30 @@ class MyUploader < Shrine
|
|
537
594
|
end
|
538
595
|
```
|
539
596
|
|
597
|
+
### Parallelize
|
598
|
+
|
599
|
+
The `parallelize` plugin has been removed. With `derivatives` plugin you can
|
600
|
+
parallelize uploading processed files manually:
|
601
|
+
|
602
|
+
```rb
|
603
|
+
# Gemfile
|
604
|
+
gem "concurrent-ruby"
|
605
|
+
```
|
606
|
+
```rb
|
607
|
+
require "concurrent"
|
608
|
+
|
609
|
+
attacher = photo.image_attacher
|
610
|
+
derivatives = attacher.process_derivatives
|
611
|
+
|
612
|
+
tasks = derivatives.map do |name, file|
|
613
|
+
Concurrent::Promises.future(name, file) do |name, file|
|
614
|
+
attacher.add_derivative(name, file)
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
Concurrent::Promises.zip(*tasks).wait!
|
619
|
+
```
|
620
|
+
|
540
621
|
### Logging
|
541
622
|
|
542
623
|
The `logging` plugin has been removed in favour of the
|
@@ -642,3 +723,4 @@ end
|
|
642
723
|
[derivatives]: https://shrinerb.com/docs/plugins/derivatives
|
643
724
|
[instrumentation]: https://shrinerb.com/docs/plugins/instrumentation
|
644
725
|
[mirroring]: https://shrinerb.com/docs/plugins/mirroring
|
726
|
+
[overwriting original]: https://discourse.shrinerb.com/t/keep-original-file-after-processing/50/4
|
data/doc/validation.md
CHANGED
@@ -88,10 +88,11 @@ when defining more validations:
|
|
88
88
|
class ApplicationUploader < Shrine
|
89
89
|
Attacher.validate { validate_max_size 5*1024*1024 }
|
90
90
|
end
|
91
|
-
|
91
|
+
```
|
92
|
+
```rb
|
92
93
|
class ImageUploader < ApplicationUploader
|
93
94
|
Attacher.validate do
|
94
|
-
super() # empty
|
95
|
+
super() # empty parentheses are required
|
95
96
|
validate_mime_type %w[image/jpeg image/png image/webp]
|
96
97
|
end
|
97
98
|
end
|
data/lib/shrine.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "shrine/version"
|
4
3
|
require "shrine/uploaded_file"
|
5
4
|
require "shrine/attacher"
|
6
5
|
require "shrine/attachment"
|
7
6
|
require "shrine/plugins"
|
7
|
+
require "shrine/version"
|
8
8
|
|
9
9
|
require "securerandom"
|
10
10
|
require "json"
|
11
11
|
require "tempfile"
|
12
12
|
require "logger"
|
13
13
|
|
14
|
-
# Core class that
|
15
|
-
# Base implementation is defined in InstanceMethods and ClassMethods.
|
14
|
+
# Core class that handles uploading files to specified storage.
|
16
15
|
class Shrine
|
17
16
|
# A generic exception used by Shrine.
|
18
|
-
class Error < StandardError
|
17
|
+
class Error < StandardError
|
18
|
+
end
|
19
19
|
|
20
20
|
# Raised when a file is not a valid IO.
|
21
21
|
class InvalidFile < Error
|
@@ -68,9 +68,9 @@ class Shrine
|
|
68
68
|
#
|
69
69
|
# Shrine.plugin MyPlugin
|
70
70
|
# Shrine.plugin :my_plugin
|
71
|
-
def plugin(plugin, *args, &block)
|
71
|
+
def plugin(plugin, *args, **kwargs, &block)
|
72
72
|
plugin = Plugins.load_plugin(plugin) if plugin.is_a?(Symbol)
|
73
|
-
|
73
|
+
Plugins.load_dependencies(plugin, self, *args, **kwargs, &block)
|
74
74
|
self.include(plugin::InstanceMethods) if defined?(plugin::InstanceMethods)
|
75
75
|
self.extend(plugin::ClassMethods) if defined?(plugin::ClassMethods)
|
76
76
|
self::UploadedFile.include(plugin::FileMethods) if defined?(plugin::FileMethods)
|
@@ -79,7 +79,7 @@ class Shrine
|
|
79
79
|
self::Attachment.extend(plugin::AttachmentClassMethods) if defined?(plugin::AttachmentClassMethods)
|
80
80
|
self::Attacher.include(plugin::AttacherMethods) if defined?(plugin::AttacherMethods)
|
81
81
|
self::Attacher.extend(plugin::AttacherClassMethods) if defined?(plugin::AttacherClassMethods)
|
82
|
-
|
82
|
+
Plugins.configure(plugin, self, *args, **kwargs, &block)
|
83
83
|
plugin
|
84
84
|
end
|
85
85
|
|
@@ -297,7 +297,7 @@ class Shrine
|
|
297
297
|
# Retrieves the location for the given IO and context. First it looks
|
298
298
|
# for the `:location` option, otherwise it calls #generate_location.
|
299
299
|
def get_location(io, location: nil, **options)
|
300
|
-
location ||= generate_location(io, options)
|
300
|
+
location ||= generate_location(io, **options)
|
301
301
|
location or fail Error, "location generated for #{io.inspect} was nil"
|
302
302
|
end
|
303
303
|
|
data/lib/shrine/attacher.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Shrine
|
4
|
-
# Core class
|
5
|
-
#
|
4
|
+
# Core class that handles attaching files. It uses Shrine and
|
5
|
+
# Shrine::UploadedFile objects internally.
|
6
6
|
class Attacher
|
7
7
|
@shrine_class = ::Shrine
|
8
8
|
|
@@ -39,16 +39,17 @@ class Shrine
|
|
39
39
|
|
40
40
|
# Initializes the attached file, temporary and permanent storage.
|
41
41
|
def initialize(file: nil, cache: :cache, store: :store)
|
42
|
-
@file
|
43
|
-
@cache
|
44
|
-
@store
|
45
|
-
@context
|
42
|
+
@file = file
|
43
|
+
@cache = cache
|
44
|
+
@store = store
|
45
|
+
@context = {}
|
46
|
+
@previous = nil
|
46
47
|
end
|
47
48
|
|
48
49
|
# Returns the temporary storage identifier.
|
49
|
-
def cache_key; @cache; end
|
50
|
+
def cache_key; @cache.to_sym; end
|
50
51
|
# Returns the permanent storage identifier.
|
51
|
-
def store_key; @store; end
|
52
|
+
def store_key; @store.to_sym; end
|
52
53
|
|
53
54
|
# Returns the uploader that is used for the temporary storage.
|
54
55
|
def cache; shrine_class.new(cache_key); end
|
@@ -69,6 +70,10 @@ class Shrine
|
|
69
70
|
def assign(value, **options)
|
70
71
|
return if value == "" # skip empty hidden field
|
71
72
|
|
73
|
+
if value.is_a?(Hash) || value.is_a?(String)
|
74
|
+
return if uploaded_file(value) == file # skip assignment for current file
|
75
|
+
end
|
76
|
+
|
72
77
|
attach_cached(value, **options)
|
73
78
|
end
|
74
79
|
|
@@ -89,7 +94,7 @@ class Shrine
|
|
89
94
|
# attacher.attach_cached({ "id" => "...", "storage" => "cache", "metadata" => {} })
|
90
95
|
def attach_cached(value, **options)
|
91
96
|
if value.is_a?(String) || value.is_a?(Hash)
|
92
|
-
change(cached(value, **options)
|
97
|
+
change(cached(value, **options))
|
93
98
|
else
|
94
99
|
attach(value, storage: cache_key, action: :cache, **options)
|
95
100
|
end
|
@@ -111,7 +116,7 @@ class Shrine
|
|
111
116
|
def attach(io, storage: store_key, **options)
|
112
117
|
file = upload(io, storage, **options) if io
|
113
118
|
|
114
|
-
change(file
|
119
|
+
change(file)
|
115
120
|
end
|
116
121
|
|
117
122
|
# Deletes any previous file and promotes newly attached cached file.
|
@@ -138,7 +143,7 @@ class Shrine
|
|
138
143
|
def finalize
|
139
144
|
destroy_previous
|
140
145
|
promote_cached
|
141
|
-
|
146
|
+
@previous = nil
|
142
147
|
end
|
143
148
|
|
144
149
|
# Plugins can override this if they want something to be done in a
|
@@ -211,7 +216,7 @@ class Shrine
|
|
211
216
|
# attacher.change(uploaded_file)
|
212
217
|
# attacher.file #=> #<Shrine::UploadedFile>
|
213
218
|
# attacher.changed? #=> true
|
214
|
-
def change(file
|
219
|
+
def change(file)
|
215
220
|
@previous = dup unless @file == file
|
216
221
|
set(file)
|
217
222
|
end
|
@@ -254,7 +259,7 @@ class Shrine
|
|
254
259
|
# attacher.attach(file)
|
255
260
|
# attacher.changed? #=> true
|
256
261
|
def changed?
|
257
|
-
|
262
|
+
!!@previous
|
258
263
|
end
|
259
264
|
|
260
265
|
# Returns whether a file is attached.
|
@@ -352,7 +357,7 @@ class Shrine
|
|
352
357
|
# reject files not uploaded to temporary storage, because otherwise
|
353
358
|
# attackers could hijack other users' attachments
|
354
359
|
unless cached?(uploaded_file)
|
355
|
-
fail Shrine::Error, "expected cached file, got #{
|
360
|
+
fail Shrine::Error, "expected cached file, got #{uploaded_file.inspect}"
|
356
361
|
end
|
357
362
|
|
358
363
|
uploaded_file
|
data/lib/shrine/attachment.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Shrine
|
4
|
-
# Core class
|
5
|
-
#
|
6
|
-
#
|
4
|
+
# Core class that provides an attachment interface for a specified attribute
|
5
|
+
# name, which can be added to model/entity classes. The model/entity plugins
|
6
|
+
# define the main interface, which delegates to a Shrine::Attacher object.
|
7
7
|
class Attachment < Module
|
8
8
|
@shrine_class = ::Shrine
|
9
9
|
|
@@ -22,8 +22,8 @@ class Shrine
|
|
22
22
|
# Shorthand for `Attachment.new`.
|
23
23
|
#
|
24
24
|
# Shrine::Attachment[:image]
|
25
|
-
def [](*args)
|
26
|
-
new(*args)
|
25
|
+
def [](*args, **options)
|
26
|
+
new(*args, **options)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|