shrine 3.4.0 → 3.5.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: 9c012576836f3a56efa91be436999395123342c4650f76f152ef64808ce82ddb
4
- data.tar.gz: 5be0e63b923ba28f838b4f692758af3eb975c937c4b63453acc629aab0240eac
3
+ metadata.gz: 46e9fa07aa69797777e3072eed12a4b901b357ae840c71f4facd5b0be2d79929
4
+ data.tar.gz: 0714e663dd130b9af96b195e5a3d87c128a0e6dd0b0598a7b2d4286e97223008
5
5
  SHA512:
6
- metadata.gz: da5eb6be96c3cacb0575e124b4238c038709d44f33085a5bfb4ae6cb1702d079ba0c7f1ca775828812c6d8cacd1b75aa5979c564dbe0e1ea52fea0036c0f577e
7
- data.tar.gz: fe12c86f5d826581e4ecb1b5e1951ca1330c8d6d288d19001badd79dab646013a2e57faf51d6cf7369669515636dda3058bf42a2128ea04934f7b611a53e97dd
6
+ metadata.gz: 87b70c2bd15dd044eacc1b2089b65bb0538728fd56dea5cce8e6e191b3bf07e63e2af45b877bfd317bcf38c98279c49d07f5d18db28d106cb08360478f1bcb76
7
+ data.tar.gz: 57703469c6efa1e724113944815dc9fb5e2a3506cf261810c07d0e40c7849bc79d2184bb576222ca7a21c56fe3f496602e93d7b60696cee763aabdaaed71cf23
data/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ ## 3.5.0 (2023-07-06)
2
+
3
+ * Migrate website to Docusaurus v2 (@janko)
4
+
5
+ * `download_endpoint` – Return `400 Bad Request` response when serialized file component is invalid (@janko)
6
+
7
+ * `base` – Stop using obsolete `URI.regexp` in `UploadedFile#extension` (@y-yagi)
8
+
9
+ * `s3` – Add `:encoding` option to `S3#open` to be passed to `Down::ChunkedIO#initialize` (@pond)
10
+
11
+ * `s3` – Add `:max_multipart_parts` option for changing default limit of 10,000 parts (@jpl)
12
+
13
+ * `s3` – Don't inherit S3 object tags when copying from temporary to permanent storage (@jrochkind)
14
+
15
+ * `infer_extension` – Add `infer_extension` instance method to the uploader for convenience (@aried3r)
16
+
17
+ * `derivation_endpoint` – Add `:signer` plugin option for providing a custom URL signer (@thibaudgg)
18
+
19
+ * `derivatives` – Don't leak `versions_compatibility: true` setting into other uploaders (@janko)
20
+
21
+ * `derivatives` – Add `:mutex` plugin option for skipping mutex and making attacher marshallable (@janko)
22
+
23
+ * `remove_attachment` – Fix passing boolean values being broken in Ruby 3.2 (@janko)
24
+
25
+ * `model` – When duplicating a record, make the duplicated attacher reference the duplicated record (@janko)
26
+
1
27
  ## 3.4.0 (2021-06-14)
2
28
 
3
29
  * `base` – Fix passing options to `Shrine.Attachment` on Ruby 3.0 (@lucianghinda)
data/README.md CHANGED
@@ -20,20 +20,20 @@ guide]**.
20
20
 
21
21
  ## Links
22
22
 
23
- | Resource | URL |
24
- | :---------------- | :----------------------------------------------------------------------------- |
25
- | Website & Documentation | [shrinerb.com](https://shrinerb.com) |
26
- | Demo code | [Roda][roda demo] / [Rails][rails demo] |
27
- | Wiki | [github.com/shrinerb/shrine/wiki](https://github.com/shrinerb/shrine/wiki) |
28
- | Help & Discussion | [discourse.shrinerb.com](https://discourse.shrinerb.com) |
23
+ | Resource | URL |
24
+ | :---------------- | :----------------------------------------------------------------------------- |
25
+ | Website & Documentation | [shrinerb.com](https://shrinerb.com) |
26
+ | Demo code | [Roda][roda demo] / [Rails][rails demo] |
27
+ | Wiki | [github.com/shrinerb/shrine/wiki](https://github.com/shrinerb/shrine/wiki) |
28
+ | Discussion forum | [github.com/shrinerb/shrine/discussions](https://github.com/shrinerb/shrine/discussions) |
29
+ | Alternate Discussion forum | [discourse.shrinerb.com](https://discourse.shrinerb.com) |
29
30
 
30
31
  ## Setup
31
32
 
32
- Add the gem to your Gemfile:
33
+ Run:
33
34
 
34
- ```rb
35
- # Gemfile
36
- gem "shrine", "~> 3.0"
35
+ ```sh
36
+ bundle add shrine
37
37
  ```
38
38
 
39
39
  Then add `config/initializers/shrine.rb` which sets up the storage and loads
@@ -80,7 +80,7 @@ allow users to upload files:
80
80
 
81
81
  ```erb
82
82
  <%= form_for @photo do |f| %>
83
- <%= f.hidden_field :image, value: @photo.cached_image_data %>
83
+ <%= f.hidden_field :image, value: @photo.cached_image_data, id: nil %>
84
84
  <%= f.file_field :image %>
85
85
  <%= f.submit %>
86
86
  <% end %>
data/doc/carrierwave.md CHANGED
@@ -368,7 +368,7 @@ Now you should be able to rewrite your application so that it uses Shrine
368
368
  instead of CarrierWave (you can consult the reference in the next section). You
369
369
  can remove the `CarrierwaveShrineSynchronization` module as well.
370
370
 
371
- ### 5. Backill metadata
371
+ ### 5. Backfill metadata
372
372
 
373
373
  You'll notice that Shrine metadata will be absent from the migrated files'
374
374
  data. You can run a script that will fill in any missing metadata defined in
@@ -646,7 +646,7 @@ Shrine.plugin :cached_attachment_data
646
646
  ```
647
647
  ```rb
648
648
  form_for @photo do |f|
649
- f.hidden_field :image, value: @photo.cached_image_data
649
+ f.hidden_field :image, value: @photo.cached_image_data, id: nil
650
650
  f.file_field :image
651
651
  end
652
652
  ```
@@ -99,11 +99,12 @@ class MoveFilesJob
99
99
 
100
100
  attacher = attacher_class.retrieve(model: record, name: name, file: file_data)
101
101
  old_attacher = attacher.dup
102
+ current_file = old_attacher.file
102
103
 
103
104
  attacher.set attacher.upload(attacher.file)
104
105
  attacher.set_derivatives attacher.upload_derivatives(attacher.derivatives)
105
106
 
106
- attacher.atomic_persist
107
+ attacher.atomic_persist(current_file)
107
108
  old_attacher.destroy_attached
108
109
  rescue Shrine::AttachmentChanged, ActiveRecord::RecordNotFound
109
110
  attacher&.destroy_attached
@@ -4,22 +4,22 @@ title: Articles
4
4
 
5
5
  ## Official articles
6
6
 
7
- | Article | Published |
8
- | :------- | --------: |
9
- | [Better File Uploads with Shrine: Eager Processing](https://twin.github.io/better-file-uploads-with-shrine-eager-processing) | 12&nbsp;Dec&nbsp;2019 |
10
- | [Shrine 3.0 Released](https://twin.github.io/shrine-3-0-released/) | 14&nbsp;Oct&nbsp;2019 |
11
- | [Upcoming Features in Shrine 3.0](https://twin.github.io/upcoming-features-in-shrine-3-0/) | 29&nbsp;Aug&nbsp;2019 |
12
- | [Better File Uploads with Shrine: Direct Uploads](https://twin.github.io/better-file-uploads-with-shrine-direct-uploads/) | 08&nbsp;Jan&nbsp;2018 |
13
- | [Better File Uploads with Shrine: Metadata](https://twin.github.io/better-file-uploads-with-shrine-metadata/) | 07&nbsp;Nov&nbsp;2016 |
14
- | [Better File Uploads with Shrine: Processing](https://twin.github.io/better-file-uploads-with-shrine-processing/) | 31&nbsp;Oct&nbsp;2016 |
15
- | [Better File Uploads with Shrine: Attachment](https://twin.github.io/better-file-uploads-with-shrine-attachment/) | 17&nbsp;Sep&nbsp;2016 |
16
- | [Better File Uploads with Shrine: Uploader](https://twin.github.io/better-file-uploads-with-shrine-uploader/) | 16&nbsp;Sep&nbsp;2016 |
17
- | [Better File Uploads with Shrine: Motivation](https://twin.github.io/better-file-uploads-with-shrine-motivation/) | 11&nbsp;Sep&nbsp;2016 |
18
- | [Resumable File Uploads in Ruby](https://twin.github.io/resumable-file-uploads-in-ruby/) | 04&nbsp;Sep&nbsp;2016 |
19
- | [Shrine meets Transloadit](https://twin.github.io/shrine-meets-transloadit/) | 11&nbsp;Jul&nbsp;2016 |
20
- | [Shrine 2.0 Released](https://twin.github.io/shrine-2-0-released/) | 20&nbsp;May&nbsp;2016 |
21
- | [Asynchronous File Uploads](http://twin.github.io/file-uploads-asynchronous-world) | 18&nbsp;Jan&nbsp;2016 |
22
- | [Introducing Shrine](http://twin.github.io/introducing-shrine) | 04&nbsp;Oct&nbsp;2015 |
7
+ | Article | Published |
8
+ | :------- | --------: |
9
+ | [Better File Uploads with Shrine: Eager Processing](https://janko.io/better-file-uploads-with-shrine-eager-processing/) | 12&nbsp;Dec&nbsp;2019 |
10
+ | [Shrine 3.0 Released](https://janko.io/shrine-3-0-released/) | 14&nbsp;Oct&nbsp;2019 |
11
+ | [Upcoming Features in Shrine 3.0](https://janko.io/upcoming-features-in-shrine-3-0/) | 29&nbsp;Aug&nbsp;2019 |
12
+ | [Better File Uploads with Shrine: Direct Uploads](https://janko.io/better-file-uploads-with-shrine-direct-uploads/) | 08&nbsp;Jan&nbsp;2018 |
13
+ | [Better File Uploads with Shrine: Metadata](https://janko.io/better-file-uploads-with-shrine-metadata/) | 07&nbsp;Nov&nbsp;2016 |
14
+ | [Better File Uploads with Shrine: Processing](https://janko.io/better-file-uploads-with-shrine-processing/) | 31&nbsp;Oct&nbsp;2016 |
15
+ | [Better File Uploads with Shrine: Attachment](https://janko.io/better-file-uploads-with-shrine-attachment/) | 17&nbsp;Sep&nbsp;2016 |
16
+ | [Better File Uploads with Shrine: Uploader](https://janko.io/better-file-uploads-with-shrine-uploader/) | 16&nbsp;Sep&nbsp;2016 |
17
+ | [Better File Uploads with Shrine: Motivation](https://janko.io/better-file-uploads-with-shrine-motivation/) | 11&nbsp;Sep&nbsp;2016 |
18
+ | [Resumable File Uploads in Ruby](https://janko.io/resumable-file-uploads-in-ruby/) | 04&nbsp;Sep&nbsp;2016 |
19
+ | [Shrine meets Transloadit](https://janko.io/shrine-meets-transloadit/) | 11&nbsp;Jul&nbsp;2016 |
20
+ | [Shrine 2.0 Released](https://janko.io/shrine-2-0-released/) | 20&nbsp;May&nbsp;2016 |
21
+ | [Asynchronous File Uploads](http://janko.io/file-uploads-asynchronous-world) | 18&nbsp;Jan&nbsp;2016 |
22
+ | [Introducing Shrine](http://janko.io/introducing-shrine) | 04&nbsp;Oct&nbsp;2015 |
23
23
 
24
24
  ## Community articles
25
25
 
@@ -35,7 +35,7 @@ title: Extensions
35
35
  | [shrine-content_addressable](https://github.com/SleeplessByte/shrine-content_addressable) | Plugin for generating content addressable locations |
36
36
  | [shrine-imgix](https://github.com/shrinerb/shrine-imgix) | Plugin for [Imgix](https://www.imgix.com/) |
37
37
  | [shrine-transloadit](https://github.com/shrinerb/shrine-transloadit) | Plugin for [Transloadit](https://transloadit.com/) |
38
- | [shrine-lambda](https://github.com/texpert/shrine-lambda) | Plugin for [AWS Lambda](https://aws.amazon.com/lambda/) |
38
+ | [shrine-aws-lambda](https://github.com/texpert/shrine-aws-lambda) | Plugin for [AWS Lambda](https://aws.amazon.com/lambda/) |
39
39
  | [hanami-shrine](https://github.com/katafrakt/hanami-shrine) | Plugin for [Hanami](https://hanamirb.org/) |
40
40
  | [shrine-mongoid](https://github.com/shrinerb/shrine-mongoid) | Plugin for [Mongoid](https://mongoid.org) |
41
41
  | [shrine-rails](https://github.com/abepetrillo/shrine-rails) | Plugin for [Rails](https://rubyonrails.org/) |
@@ -3,6 +3,9 @@ id: getting-started
3
3
  title: Getting Started
4
4
  ---
5
5
 
6
+ import Tabs from '@theme/Tabs';
7
+ import TabItem from '@theme/TabItem';
8
+
6
9
  ## Quick start
7
10
 
8
11
  Add Shrine to the Gemfile and write an initializer which sets up the storage
@@ -32,32 +35,39 @@ Next decide how you will name the attachment attribute on your model, and run a
32
35
  migration that adds an `<attachment>_data` text or JSON column, which Shrine
33
36
  will use to store all information about the attachment:
34
37
 
35
- <!--DOCUSAURUS_CODE_TABS-->
36
- <!--Sequel-->
38
+ <Tabs>
39
+ <TabItem value="sequel" label="Sequel">
40
+
37
41
  ```rb
38
42
  Sequel.migration do
39
43
  change do
40
- add_column :photos, :image_data, :text # or :jsonb
44
+ add_column :photos, :image_data, :text # or :jsonb
41
45
  end
42
46
  end
43
47
  ```
44
48
 
45
- <!--ActiveRecord-->
49
+ </TabItem>
50
+ <TabItem value="activerecord" label="Active Record">
51
+
46
52
  ```rb
47
53
  class AddImageDataToPhotos < ActiveRecord::Migration
48
54
  def change
49
- add_column :photos, :image_data, :text # or :jsonb
55
+ add_column :photos, :image_data, :text # or :jsonb
50
56
  end
51
57
  end
52
58
  ```
53
59
 
54
- <!--Rails-->
60
+ </TabItem>
61
+ <TabItem value="rails" label="Rails">
62
+
55
63
  ```rb
56
- $ rails generate migration add_image_data_to_photos image_data:text # or image_data:jsonb
64
+ $ rails generate migration add_image_data_to_photos image_data:text # or image_data:jsonb
57
65
  ```
58
- If using `jsonb` consider adding a [gin index] for fast key-value pair searchability within `image_data`.
59
66
 
60
- <!--END_DOCUSAURUS_CODE_TABS-->
67
+ </TabItem>
68
+ </Tabs>
69
+
70
+ If using `jsonb` consider adding a [gin index] for fast key-value pair searchability within `image_data`.
61
71
 
62
72
  Now you can create an uploader class for the type of files you want to upload,
63
73
  and add a virtual attribute for handling attachments using this uploader to
@@ -69,36 +79,47 @@ class ImageUploader < Shrine
69
79
  # plugins and uploading logic
70
80
  end
71
81
  ```
72
- <!--DOCUSAURUS_CODE_TABS-->
73
- <!--Sequel-->
82
+
83
+ <Tabs>
84
+ <TabItem value="sequel" label="Sequel">
85
+
74
86
  ```rb
75
87
  class Photo < Sequel::Model
76
88
  include ImageUploader::Attachment(:image) # adds an `image` virtual attribute
77
89
  end
78
90
  ```
79
- <!--ActiveRecord-->
91
+
92
+ </TabItem>
93
+ <TabItem value="activerecord" label="Active Record">
94
+
80
95
  ```rb
81
96
  class Photo < ActiveRecord::Base
82
97
  include ImageUploader::Attachment(:image) # adds an `image` virtual attribute
83
98
  end
84
99
  ```
85
- <!--END_DOCUSAURUS_CODE_TABS-->
100
+
101
+ </TabItem>
102
+ </Tabs>
86
103
 
87
104
  Let's now add the form fields which will use this virtual attribute (NOT the
88
105
  `<attachment>_data` column attribute). We need (1) a file field for choosing
89
106
  files, and (2) a hidden field for retaining the uploaded file in case of
90
107
  validation errors and for potential [direct uploads].
91
108
 
92
- <!--DOCUSAURUS_CODE_TABS-->
93
- <!--Rails form builder-->
109
+ <Tabs>
110
+ <TabItem value="rails" label="Rails form builder">
111
+
94
112
  ```rb
95
113
  form_for @photo do |f|
96
- f.hidden_field :image, value: @photo.cached_image_data
114
+ f.hidden_field :image, value: @photo.cached_image_data, id: nil
97
115
  f.file_field :image
98
116
  f.submit
99
117
  end
100
118
  ```
101
- <!--Simple Form-->
119
+
120
+ </TabItem>
121
+ <TabItem value="simple_form" label="Simple Form">
122
+
102
123
  ```rb
103
124
  simple_form_for @photo do |f|
104
125
  f.input :image, as: :hidden, input_html: { value: @photo.cached_image_data }
@@ -106,7 +127,10 @@ simple_form_for @photo do |f|
106
127
  f.button :submit
107
128
  end
108
129
  ```
109
- <!--Forme-->
130
+
131
+ </TabItem>
132
+ <TabItem value="form" label="Forme">
133
+
110
134
  ```rb
111
135
  form @photo, action: "/photos", enctype: "multipart/form-data" do |f|
112
136
  f.input :image, type: :hidden, value: @photo.cached_image_data
@@ -114,7 +138,10 @@ form @photo, action: "/photos", enctype: "multipart/form-data" do |f|
114
138
  f.button "Create"
115
139
  end
116
140
  ```
117
- <!--HTML-->
141
+
142
+ </TabItem>
143
+ <TabItem value="html" label="HTML">
144
+
118
145
  ```erb
119
146
  <form action="/photos" method="post" enctype="multipart/form-data">
120
147
  <input name="photo[image]" type="hidden" value="<%= @photo.cached_image_data %>" />
@@ -122,7 +149,9 @@ end
122
149
  <input type="submit" value="Create" />
123
150
  </form>
124
151
  ```
125
- <!--END_DOCUSAURUS_CODE_TABS-->
152
+
153
+ </TabItem>
154
+ </Tabs>
126
155
 
127
156
  Note that the file field needs to go *after* the hidden field, so that
128
157
  selecting a new file can always override the cached file in the hidden field.
@@ -133,8 +162,9 @@ will automatically generate this for you).
133
162
  When the form is submitted, in your router/controller you can assign the file
134
163
  from request params to the attachment attribute on the model.
135
164
 
136
- <!--DOCUSAURUS_CODE_TABS-->
137
- <!--Rails-->
165
+ <Tabs>
166
+ <TabItem value="rails" label="Rails">
167
+
138
168
  ```rb
139
169
  class PhotosController < ApplicationController
140
170
  def create
@@ -149,28 +179,39 @@ class PhotosController < ApplicationController
149
179
  end
150
180
  end
151
181
  ```
152
- <!--Sinatra-->
182
+
183
+ </TabItem>
184
+ <TabItem value="sinatra" label="Sinatra">
185
+
153
186
  ```rb
154
187
  post "/photos" do
155
188
  Photo.create(params[:photo])
156
189
  # ...
157
190
  end
158
191
  ```
159
- <!--END_DOCUSAURUS_CODE_TABS-->
192
+
193
+ </TabItem>
194
+ </Tabs>
160
195
 
161
196
  Once a file is uploaded and attached to the record, you can retrieve a URL to
162
197
  the uploaded file with `#<attachment>_url` and display it on the page:
163
198
 
164
- <!--DOCUSAURUS_CODE_TABS-->
165
- <!--Rails-->
199
+ <Tabs>
200
+ <TabItem value="rails" label="Rails">
201
+
166
202
  ```erb
167
203
  <%= image_tag @photo.image_url %>
168
204
  ```
169
- <!--HTML-->
205
+
206
+ </TabItem>
207
+ <TabItem value="html" label="HTML">
208
+
170
209
  ```erb
171
210
  <img src="<%= @photo.image_url %>" />
172
211
  ```
173
- <!--END_DOCUSAURUS_CODE_TABS-->
212
+
213
+ </TabItem>
214
+ </Tabs>
174
215
 
175
216
  ## Storage
176
217
 
@@ -3,6 +3,9 @@ id: multiple-files
3
3
  title: Multiple Files
4
4
  ---
5
5
 
6
+ import Tabs from '@theme/Tabs';
7
+ import TabItem from '@theme/TabItem';
8
+
6
9
  There are times when you want to allow users to attach multiple files to a
7
10
  single resource, like an album having many photos or a playlist having many
8
11
  songs. Some file attachment libraries provide a special interface for multiple
@@ -67,8 +70,9 @@ files (or attachments) table will be the photos table.
67
70
  Let's create a table for the main resource and attachments, and add a foreign
68
71
  key in the attachment table for the main table:
69
72
 
70
- <!--DOCUSAURUS_CODE_TABS-->
71
- <!--Sequel-->
73
+ <Tabs>
74
+ <TabItem value="sequel" label="Sequel">
75
+
72
76
  ```rb
73
77
  Sequel.migration do
74
78
  change do
@@ -87,7 +91,10 @@ Sequel.migration do
87
91
  end
88
92
  end
89
93
  ```
90
- <!--ActiveRecord-->
94
+
95
+ </TabItem>
96
+ <TabItem value="activerecord" label="Active Record">
97
+
91
98
  ```rb
92
99
  class CreateAlbumsAndPhotos < ActiveRecord::Migration
93
100
  def change
@@ -104,25 +111,33 @@ class CreateAlbumsAndPhotos < ActiveRecord::Migration
104
111
  end
105
112
  end
106
113
  ```
107
- <!--END_DOCUSAURUS_CODE_TABS-->
114
+
115
+ </TabItem>
116
+ </Tabs>
108
117
 
109
118
  In the Photo model, create a Shrine attachment attribute named `image`
110
119
  (`:image` matches the `_data` column prefix above):
111
120
 
112
- <!--DOCUSAURUS_CODE_TABS-->
113
- <!--Sequel-->
121
+ <Tabs>
122
+ <TabItem value="sequel" label="Sequel">
123
+
114
124
  ```rb
115
125
  class Photo < Sequel::Model
116
126
  include ImageUploader::Attachment(:image)
117
127
  end
118
128
  ```
119
- <!--ActiveRecord-->
129
+
130
+ </TabItem>
131
+ <TabItem value="activerecord" label="Active Record">
132
+
120
133
  ```rb
121
134
  class Photo < ActiveRecord::Base
122
135
  include ImageUploader::Attachment(:image)
123
136
  end
124
137
  ```
125
- <!--END_DOCUSAURUS_CODE_TABS-->
138
+
139
+ </TabItem>
140
+ </Tabs>
126
141
 
127
142
  ### 2. Declare nested attributes
128
143
 
@@ -131,8 +146,9 @@ Using nested attributes is the easiest way to implement any dynamic
131
146
  relationship to the photos table, and allow it to directly accept attributes
132
147
  for the associated photo records by enabling nested attributes:
133
148
 
134
- <!--DOCUSAURUS_CODE_TABS-->
135
- <!--Sequel-->
149
+ <Tabs>
150
+ <TabItem value="sequel" label="Sequel">
151
+
136
152
  ```rb
137
153
  class Album < Sequel::Model
138
154
  one_to_many :photos
@@ -142,14 +158,20 @@ class Album < Sequel::Model
142
158
  nested_attributes :photos, destroy: true
143
159
  end
144
160
  ```
145
- <!--ActiveRecord-->
161
+
162
+ </TabItem>
163
+ <TabItem value="activerecord" label="Active Record">
164
+
146
165
  ```rb
147
166
  class Album < ActiveRecord::Base
148
167
  has_many :photos, dependent: :destroy
149
168
  accepts_nested_attributes_for :photos, allow_destroy: true
150
169
  end
151
170
  ```
152
- <!--Mongoid-->
171
+
172
+ </TabItem>
173
+ <TabItem value="mongoid" label="Mongoid">
174
+
153
175
  ```rb
154
176
  class Album
155
177
  include Mongoid::Document
@@ -157,7 +179,9 @@ class Album
157
179
  accepts_nested_attributes_for :photos
158
180
  end
159
181
  ```
160
- <!--END_DOCUSAURUS_CODE_TABS-->
182
+
183
+ </TabItem>
184
+ </Tabs>
161
185
 
162
186
  Documentation on nested attributes:
163
187
 
@@ -174,13 +198,14 @@ already created photos, so that the same form can be used for updating the
174
198
  album/photos as well (they will be submitted under the
175
199
  `album[photos_attributes]` parameter).
176
200
 
177
- <!--DOCUSAURUS_CODE_TABS-->
178
- <!--Rails form builder-->
201
+ <Tabs>
202
+ <TabItem value="rails" label="Rails form builder">
203
+
179
204
  ```rb
180
205
  form_for @album, html: { enctype: "multipart/form-data" } do |f|
181
206
  f.text_field :title
182
207
  f.fields_for :photos do |p| # adds new `album[photos_attributes]` parameter
183
- p.hidden_field :image, value: p.object.cached_image_data
208
+ p.hidden_field :image, value: p.object.cached_image_data, id: nil
184
209
  p.file_field :image
185
210
  p.check_box :_destroy unless p.object.new_record?
186
211
  end
@@ -188,7 +213,10 @@ form_for @album, html: { enctype: "multipart/form-data" } do |f|
188
213
  f.submit "Create"
189
214
  end
190
215
  ```
191
- <!--Forme-->
216
+
217
+ </TabItem>
218
+ <TabItem value="forme" label="Forme">
219
+
192
220
  ```rb
193
221
  form @album, action: "/photos", enctype: "multipart/form-data" do |f|
194
222
  f.input :title
@@ -201,7 +229,9 @@ form @album, action: "/photos", enctype: "multipart/form-data" do |f|
201
229
  f.button "Create"
202
230
  end
203
231
  ```
204
- <!--END_DOCUSAURUS_CODE_TABS-->
232
+
233
+ </TabItem>
234
+ </Tabs>
205
235
 
206
236
  In your controller you should still be able to assign all the attributes to the
207
237
  album, just remember to whitelist the new parameter for the nested attributes,
@@ -286,21 +316,26 @@ class ImageUploader < Shrine
286
316
  end
287
317
  end
288
318
  ```
289
- <!--DOCUSAURUS_CODE_TABS-->
290
- <!--Sequel-->
319
+ <Tabs>
320
+ <TabItem value="sequel" label="Sequel">
321
+
291
322
  ```rb
292
323
  class Album < Sequel::Model
293
324
  # ... (nested_attributes already enables validating associated photos) ...
294
325
  end
295
326
  ```
296
- <!--ActiveRecord-->
327
+
328
+ </TabItem>
329
+ <TabItem value="activerecord" label="Active Record">
330
+
297
331
  ```rb
298
332
  class Album < ActiveRecord::Base
299
333
  # ...
300
334
  validates_associated :photos
301
335
  end
302
336
  ```
303
- <!--END_DOCUSAURUS_CODE_TABS-->
337
+ </TabItem>
338
+ </Tabs>
304
339
 
305
340
  Note that by default only metadata set on the client side will be available for
306
341
  validations. Shrine will not automatically run metadata extraction for directly
@@ -46,7 +46,7 @@ Then, in your initializer, you can configure all uploaders to use these jobs:
46
46
 
47
47
  ```rb
48
48
  Shrine::Attacher.promote_block do
49
- PromoteJob.perform_async(self.class.name, record.class.name, record.id, name, file_data)
49
+ PromoteJob.perform_async(self.class.name, record.class.name, record.id, name.to_s, file_data)
50
50
  end
51
51
  Shrine::Attacher.destroy_block do
52
52
  DestroyJob.perform_async(self.class.name, data)
@@ -58,7 +58,7 @@ Alternatively, you can setup backgrounding only for specific uploaders:
58
58
  ```rb
59
59
  class MyUploader < Shrine
60
60
  Attacher.promote_block do
61
- PromoteJob.perform_async(self.class.name, record.class.name, record.id, name, file_data)
61
+ PromoteJob.perform_async(self.class.name, record.class.name, record.id, name.to_s, file_data)
62
62
  end
63
63
  Attacher.destroy_block do
64
64
  DestroyJob.perform_async(self.class.name, data)
@@ -121,7 +121,7 @@ Shrine::Attacher.promote_block do |attacher|
121
121
  attacher.class.name,
122
122
  attacher.record.class.name,
123
123
  attacher.record.id,
124
- attacher.name,
124
+ attacher.name.to_s,
125
125
  attacher.file_data,
126
126
  )
127
127
  end
@@ -143,7 +143,7 @@ photo.image_attacher.promote_block do |attacher|
143
143
  attacher.class.name,
144
144
  attacher.record.class.name,
145
145
  attacher.record.id,
146
- attacher.name,
146
+ attacher.name.to_s,
147
147
  attacher.file_data,
148
148
  current_user.id, # pass arguments known at the controller level
149
149
  )
@@ -331,6 +331,29 @@ uploaded_file.derivation_url(:thumbnail, expires_in: 90)
331
331
  #=> ".../thumbnail/eyJpZCI6ImZvbyIsInN?expires_at=1547843568&signature=..."
332
332
  ```
333
333
 
334
+ ## Custom signer
335
+
336
+ The derivation URLs are signed by default, and the signature is checked when
337
+ the URLs are requested, which prevents tampering. If you have URL expiration
338
+ turned on, this may prevent your CDN from caching the response.
339
+
340
+ In this case, you may need to do custom CDN-specific URL signing. You can
341
+ bypass Shrine's default signing by passing a custom signer:
342
+
343
+ ```rb
344
+ require "aws-sdk-cloudfront"
345
+ signer = Aws::CloudFront::UrlSigner.new(key_pair_id: "...", private_key: "...")
346
+
347
+ plugin :derivation_endpoint,
348
+ expires_in: 90,
349
+ signer: -> (url, expires_in:) do
350
+ signer.signed_url(url, expires: Time.now.to_i + expires_in)
351
+ end
352
+ ```
353
+
354
+ When `:signer` option is used, the `:secret_key` option is not required, as
355
+ that secret is only used for default signing.
356
+
334
357
  ## Response headers
335
358
 
336
359
  ### Content Type
@@ -796,6 +819,7 @@ derivation.option(:upload_location)
796
819
  | `:metadata` | List of metadata keys the source uploaded file should include in the derivation block | `[]` |
797
820
  | `:prefix` | Path prefix added to the URLs | `nil` |
798
821
  | `:secret_key` | Key used to sign derivation URLs in order to prevent tampering | required |
822
+ | `:signer` | Proc accepting URL and query params used for custom signing of URLs. | `nil` |
799
823
  | `:type` | Media type returned in the `Content-Type` response header in the derivation response | determined from derivative's extension when possible |
800
824
  | `:upload` | Whether the generated derivatives will be cached on the storage | `false` |
801
825
  | `:upload_location` | Location to which the derivatives will be uploaded on the storage | `<source id>/<name>-<args>` |
@@ -133,7 +133,7 @@ Attacher.default_url do |derivative: nil, **|
133
133
  end
134
134
  ```
135
135
  ```rb
136
- photo.image_url(:medium) #=> "https://example.com/fallbacks.com/medium.jpg"
136
+ photo.image_url(:medium) #=> "https://example.com/fallbacks/medium.jpg"
137
137
  ```
138
138
 
139
139
  Any additional URL options passed to `#<name>_url` will be forwarded to the
@@ -778,6 +778,16 @@ derivatives #=>
778
778
  Like `Shrine.uploaded_file`, the `Shrine.derivatives` method accepts data as a
779
779
  hash (stringified or symbolized) or a JSON string.
780
780
 
781
+ ### Marshalling
782
+
783
+ The `Attacher` instance uses a mutex to make `Attacher#merge_derivatives`
784
+ thread-safe, which is not marshallable. If you want to be able to marshal the
785
+ attacher instance, you can skip mutex usage:
786
+
787
+ ```rb
788
+ plugin :derivatives, mutex: false
789
+ ```
790
+
781
791
  ## Instrumentation
782
792
 
783
793
  If the `instrumentation` plugin has been loaded, the `derivatives` plugin adds