shrine 2.19.4 → 3.0.0.alpha
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 +299 -11
- data/README.md +9 -3
- data/doc/advantages.md +1 -1
- data/doc/carrierwave.md +4 -4
- data/doc/creating_persistence_plugins.md +172 -0
- data/doc/creating_plugins.md +1 -1
- data/doc/creating_storages.md +3 -1
- data/doc/design.md +2 -2
- data/doc/direct_s3.md +0 -22
- data/doc/paperclip.md +3 -3
- data/doc/plugins/activerecord.md +211 -42
- data/doc/plugins/atomic_helpers.md +153 -0
- data/doc/plugins/column.md +90 -0
- data/doc/plugins/derivation_endpoint.md +54 -62
- data/doc/plugins/derivatives.md +752 -0
- data/doc/plugins/entity.md +204 -0
- data/doc/plugins/infer_extension.md +8 -8
- data/doc/plugins/instrumentation.md +33 -13
- data/doc/plugins/keep_files.md +5 -15
- data/doc/plugins/model.md +157 -0
- data/doc/plugins/presign_endpoint.md +2 -1
- data/doc/plugins/refresh_metadata.md +44 -7
- data/doc/plugins/sequel.md +190 -33
- data/doc/plugins/{default_url_options.md → url_options.md} +5 -5
- data/doc/processing.md +1 -1
- data/doc/release_notes/1.1.0.md +2 -2
- data/doc/release_notes/2.15.0.md +1 -1
- data/doc/storage/s3.md +2 -2
- data/doc/testing.md +1 -1
- data/lib/shrine.rb +72 -138
- data/lib/shrine/attacher.rb +272 -176
- data/lib/shrine/attachment.rb +2 -42
- data/lib/shrine/plugins/activerecord.rb +103 -26
- data/lib/shrine/plugins/add_metadata.rb +9 -10
- data/lib/shrine/plugins/atomic_helpers.rb +111 -0
- data/lib/shrine/plugins/attacher_options.rb +55 -0
- data/lib/shrine/plugins/backgrounding.rb +147 -115
- data/lib/shrine/plugins/cached_attachment_data.rb +6 -9
- data/lib/shrine/plugins/column.rb +104 -0
- data/lib/shrine/plugins/data_uri.rb +35 -38
- data/lib/shrine/plugins/default_storage.rb +18 -12
- data/lib/shrine/plugins/default_url.rb +11 -21
- data/lib/shrine/plugins/default_url_options.rb +3 -30
- data/lib/shrine/plugins/delete_raw.rb +9 -13
- data/lib/shrine/plugins/derivation_endpoint.rb +75 -114
- data/lib/shrine/plugins/derivatives.rb +576 -0
- data/lib/shrine/plugins/determine_mime_type.rb +3 -15
- data/lib/shrine/plugins/download_endpoint.rb +83 -131
- data/lib/shrine/plugins/dynamic_storage.rb +4 -8
- data/lib/shrine/plugins/entity.rb +128 -0
- data/lib/shrine/plugins/form_assign.rb +107 -0
- data/lib/shrine/plugins/included.rb +4 -3
- data/lib/shrine/plugins/infer_extension.rb +10 -17
- data/lib/shrine/plugins/instrumentation.rb +45 -25
- data/lib/shrine/plugins/keep_files.rb +2 -12
- data/lib/shrine/plugins/metadata_attributes.rb +15 -14
- data/lib/shrine/plugins/model.rb +137 -0
- data/lib/shrine/plugins/module_include.rb +2 -0
- data/lib/shrine/plugins/presign_endpoint.rb +1 -15
- data/lib/shrine/plugins/pretty_location.rb +5 -5
- data/lib/shrine/plugins/processing.rb +21 -6
- data/lib/shrine/plugins/rack_file.rb +1 -39
- data/lib/shrine/plugins/rack_response.rb +14 -7
- data/lib/shrine/plugins/recache.rb +5 -2
- data/lib/shrine/plugins/refresh_metadata.rb +12 -8
- data/lib/shrine/plugins/remote_url.rb +44 -53
- data/lib/shrine/plugins/remove_attachment.rb +7 -2
- data/lib/shrine/plugins/remove_invalid.rb +8 -4
- data/lib/shrine/plugins/restore_cached_data.rb +12 -4
- data/lib/shrine/plugins/sequel.rb +115 -27
- data/lib/shrine/plugins/signature.rb +2 -7
- data/lib/shrine/plugins/store_dimensions.rb +13 -27
- data/lib/shrine/plugins/upload_endpoint.rb +14 -15
- data/lib/shrine/plugins/upload_options.rb +9 -8
- data/lib/shrine/plugins/url_options.rb +33 -0
- data/lib/shrine/plugins/validation.rb +87 -0
- data/lib/shrine/plugins/validation_helpers.rb +33 -54
- data/lib/shrine/plugins/versions.rb +106 -84
- data/lib/shrine/storage/file_system.rb +32 -57
- data/lib/shrine/storage/linter.rb +9 -1
- data/lib/shrine/storage/memory.rb +42 -0
- data/lib/shrine/storage/s3.rb +38 -146
- data/lib/shrine/uploaded_file.rb +22 -29
- data/lib/shrine/version.rb +4 -4
- data/shrine.gemspec +2 -3
- metadata +27 -54
- data/doc/plugins/backup.md +0 -31
- data/doc/plugins/copy.md +0 -24
- data/doc/plugins/delete_promoted.md +0 -12
- data/doc/plugins/direct_upload.md +0 -172
- data/doc/plugins/hooks.md +0 -58
- data/doc/plugins/logging.md +0 -42
- data/doc/plugins/migration_helpers.md +0 -60
- data/doc/plugins/moving.md +0 -19
- data/doc/plugins/multi_delete.md +0 -20
- data/doc/plugins/parallelize.md +0 -16
- data/doc/plugins/parsed_json.md +0 -23
- data/lib/shrine/plugins/background_helpers.rb +0 -5
- data/lib/shrine/plugins/backup.rb +0 -90
- data/lib/shrine/plugins/copy.rb +0 -50
- data/lib/shrine/plugins/delete_promoted.rb +0 -20
- data/lib/shrine/plugins/direct_upload.rb +0 -217
- data/lib/shrine/plugins/hooks.rb +0 -90
- data/lib/shrine/plugins/logging.rb +0 -142
- data/lib/shrine/plugins/migration_helpers.rb +0 -70
- data/lib/shrine/plugins/moving.rb +0 -57
- data/lib/shrine/plugins/multi_delete.rb +0 -32
- data/lib/shrine/plugins/parallelize.rb +0 -78
- data/lib/shrine/plugins/parsed_json.rb +0 -29
@@ -0,0 +1,204 @@
|
|
1
|
+
# Entity
|
2
|
+
|
3
|
+
The [`entity`][entity] plugin provides integration for handling attachments on
|
4
|
+
immutable structs. It is built on top of the [`column`][column] plugin.
|
5
|
+
|
6
|
+
```rb
|
7
|
+
plugin :entity
|
8
|
+
```
|
9
|
+
|
10
|
+
## Attachment
|
11
|
+
|
12
|
+
Including a `Shrine::Attachment` module into an entity class will add the
|
13
|
+
following instance methods:
|
14
|
+
|
15
|
+
* `#<name>` – returns the attached file
|
16
|
+
* `#<name>_url` – returns the attached file URL
|
17
|
+
* `#<name>_attacher` – returns a `Shrine::Attacher` instance
|
18
|
+
|
19
|
+
These methods read attachment data from the `#<name>_data` attribute on the
|
20
|
+
entity instance.
|
21
|
+
|
22
|
+
```rb
|
23
|
+
class Photo < Entity(:image_data)
|
24
|
+
include ImageUploader::Attachment(:image)
|
25
|
+
end
|
26
|
+
```
|
27
|
+
```rb
|
28
|
+
photo = Photo.new(image_data: '{"id":"...","storage":"...","metadata":{...}}')
|
29
|
+
photo.image #=> #<ImageUploader::UploadedFile>
|
30
|
+
photo.image_url #=> "https://example.com/image.jpg"
|
31
|
+
photo.image_attacher #=> #<ImageUploader::Attacher>
|
32
|
+
```
|
33
|
+
|
34
|
+
#### `#<name>`
|
35
|
+
|
36
|
+
Calls `Attacher#get`, which returns an `UploadedFile` object instantiated from
|
37
|
+
attachment data.
|
38
|
+
|
39
|
+
```rb
|
40
|
+
photo = Photo.new(image_data: '{"id":"foo.jpg","storage":"store","metadata":{...}}')
|
41
|
+
photo.image #=> #<ImageUploader::UploadedFile>
|
42
|
+
photo.image.id #=> "foo.jpg"
|
43
|
+
photo.image.storage_key #=> :store
|
44
|
+
photo.image.metadata #=> { ... }
|
45
|
+
```
|
46
|
+
|
47
|
+
If no file is attached, `nil` is returned.
|
48
|
+
|
49
|
+
```rb
|
50
|
+
photo = Photo.new(image_data: nil)
|
51
|
+
photo.image #=> nil
|
52
|
+
```
|
53
|
+
|
54
|
+
#### `#<name>_url`
|
55
|
+
|
56
|
+
Calls `Attacher#url`, which returns the URL to the attached file.
|
57
|
+
|
58
|
+
```rb
|
59
|
+
photo = Photo.new(image_data: {"id":"foo.jpg","storage":"...","metadata":{...}})
|
60
|
+
photo.image_url #=> "https://example.com/foo.jpg"
|
61
|
+
```
|
62
|
+
|
63
|
+
If no file is attached, `nil` is returned.
|
64
|
+
|
65
|
+
```rb
|
66
|
+
photo = Photo.new(image_data: nil)
|
67
|
+
photo.image_url #=> nil
|
68
|
+
```
|
69
|
+
|
70
|
+
#### `#<name>_attacher`
|
71
|
+
|
72
|
+
Calls `Attacher.from_entity`, which returns an `Attacher` instance backed by
|
73
|
+
the entity object.
|
74
|
+
|
75
|
+
```rb
|
76
|
+
photo = Photo.new
|
77
|
+
photo.image_attacher #=> #<ImageUploader::Attacher>
|
78
|
+
photo.image_attacher.record #=> #<Photo>
|
79
|
+
photo.image_attacher.name #=> :image
|
80
|
+
photo.image_attacher.attribute #=> :image_data
|
81
|
+
```
|
82
|
+
|
83
|
+
Any additional options will be forwarded to `Attacher#initialize`.
|
84
|
+
|
85
|
+
```rb
|
86
|
+
photo = Photo.new
|
87
|
+
attacher = photo.image_attacher(cache: :other_cache)
|
88
|
+
attacher.cache_key #=> :other_cache
|
89
|
+
```
|
90
|
+
|
91
|
+
You can also specify default attacher options when including
|
92
|
+
`Shrine::Attachment`:
|
93
|
+
|
94
|
+
```rb
|
95
|
+
class Photo < Entity(:image_data)
|
96
|
+
include ImageUploader::Attachment(:image, store: :other_store)
|
97
|
+
end
|
98
|
+
```
|
99
|
+
```rb
|
100
|
+
photo = Photo.new
|
101
|
+
attacher = photo.image_attacher
|
102
|
+
attacher.store_key #=> :other_store
|
103
|
+
```
|
104
|
+
|
105
|
+
## Attacher
|
106
|
+
|
107
|
+
### Loading entity
|
108
|
+
|
109
|
+
The `Attacher.from_entity` method can be used for creating an `Attacher`
|
110
|
+
instance backed by an entity object.
|
111
|
+
|
112
|
+
```rb
|
113
|
+
photo = Photo.new(image_data: '{"id":"...","storage":"...","metadata":{...}}')
|
114
|
+
attacher = ImageUploader::Attacher.from_entity(photo, :image)
|
115
|
+
|
116
|
+
attacher.record #=> #<Photo>
|
117
|
+
attacher.name #=> :image
|
118
|
+
attacher.attribute #=> :image_data
|
119
|
+
|
120
|
+
attacher.file #=> #<ImageUploader::UploadedFile>
|
121
|
+
```
|
122
|
+
|
123
|
+
Any additional options are forwarded to `Attacher#initialize`.
|
124
|
+
|
125
|
+
```rb
|
126
|
+
attacher = ImageUploader::Attacher.from_entity(photo, :image, cache: :other_cache)
|
127
|
+
attacher.cache_key #=> :other_cache
|
128
|
+
```
|
129
|
+
|
130
|
+
You can also load an entity into an existing attacher with
|
131
|
+
`Attacher#load_entity`.
|
132
|
+
|
133
|
+
```rb
|
134
|
+
photo = Photo.new(image_data: '{"id":"...","storage":"...","metadata":{...}}')
|
135
|
+
|
136
|
+
attacher.file #=> nil
|
137
|
+
attacher.load_entity(photo, :image)
|
138
|
+
attacher.file #=> #<ImageUploader::UploadedFile>
|
139
|
+
```
|
140
|
+
|
141
|
+
### Reloading
|
142
|
+
|
143
|
+
The `Attacher#reload` method reloads attached file from the attachment data on
|
144
|
+
the entity attribute.
|
145
|
+
|
146
|
+
```rb
|
147
|
+
photo = Photo.new
|
148
|
+
|
149
|
+
attacher = ImageUploader::Attacher.from_entity(photo, :image)
|
150
|
+
attacher.file #=> nil
|
151
|
+
|
152
|
+
photo.image_data = '{"id":"...","storage":"...","metadata":{...}}'
|
153
|
+
|
154
|
+
attacher.file #=> nil
|
155
|
+
attacher.reload
|
156
|
+
attacher.file #=> #<ImageUploader::UploadedFile>
|
157
|
+
```
|
158
|
+
|
159
|
+
### Column values
|
160
|
+
|
161
|
+
The `Attacher#column_values` method returns a hash with the entity attribute as
|
162
|
+
key and current attachment data as value.
|
163
|
+
|
164
|
+
```rb
|
165
|
+
attacher = ImageUploader::Attacher.from_entity(Photo.new, :image)
|
166
|
+
attacher.attach(io)
|
167
|
+
|
168
|
+
attacher.column_values #=> { :image_data => '{"id":"...","storage":"...","metadata":{...}}' }
|
169
|
+
```
|
170
|
+
|
171
|
+
The `Attacher#attribute` method returns just the entity attribute from which
|
172
|
+
attached file data is read.
|
173
|
+
|
174
|
+
```rb
|
175
|
+
attacher = ImageUploader::Attacher.from_entity(Photo.new, :image)
|
176
|
+
attacher.attribute #=> :image_data
|
177
|
+
```
|
178
|
+
|
179
|
+
### Entity data
|
180
|
+
|
181
|
+
The `Attacher#record` method returns the entity instance from which the
|
182
|
+
attacher was loaded.
|
183
|
+
|
184
|
+
```rb
|
185
|
+
attacher = ImageUploader::Attacher.from_entity(Photo.new, :image)
|
186
|
+
attacher.record #=> #<Photo>
|
187
|
+
```
|
188
|
+
|
189
|
+
The `Attacher#name` method returns the name of the attachment from which the
|
190
|
+
attacher was loaded.
|
191
|
+
|
192
|
+
```rb
|
193
|
+
attacher = ImageUploader::Attacher.from_entity(Photo.new, :image)
|
194
|
+
attacher.name #=> :image
|
195
|
+
```
|
196
|
+
|
197
|
+
## Serialization
|
198
|
+
|
199
|
+
By default, attachment data is serialized into JSON using the `JSON` standard
|
200
|
+
library. If you want to change how data is serialized, see the
|
201
|
+
[`column`][column serializer] plugin docs.
|
202
|
+
|
203
|
+
[entity]: /lib/shrine/plugins/entity.rb
|
204
|
+
[column serializer]: /doc/plugins/column.md#serializer
|
@@ -11,19 +11,19 @@ plugin :infer_extension
|
|
11
11
|
|
12
12
|
## Inferrers
|
13
13
|
|
14
|
-
By default
|
15
|
-
also choose a different inferrer:
|
14
|
+
By default, the [mini_mime] gem will be used for inferring the extension, but
|
15
|
+
you can also choose a different inferrer:
|
16
16
|
|
17
17
|
```rb
|
18
|
-
plugin :infer_extension, inferrer: :
|
18
|
+
plugin :infer_extension, inferrer: :mime_types
|
19
19
|
```
|
20
20
|
|
21
21
|
The following inferrers are accepted:
|
22
22
|
|
23
|
-
| Name | Description
|
24
|
-
| :------------ | :-----------
|
25
|
-
| `:
|
26
|
-
| `:
|
23
|
+
| Name | Description |
|
24
|
+
| :------------ | :----------- |
|
25
|
+
| `:mini_mime` | (Default). Uses the [mini_mime] gem to infer the appropriate extension from MIME type. |
|
26
|
+
| `:mime_types` | Uses the [mime-types] gem to infer the appropriate extension from MIME type. |
|
27
27
|
|
28
28
|
You can also define your own inferrer, with the possibility to call the
|
29
29
|
built-in inferrers:
|
@@ -31,7 +31,7 @@ built-in inferrers:
|
|
31
31
|
```rb
|
32
32
|
plugin :infer_extension, inferrer: -> (mime_type, inferrers) do
|
33
33
|
# don't add extension if the file is a text file
|
34
|
-
inferrers[:
|
34
|
+
inferrers[:mini_mime].call(mime_type) unless mime_type == "text/plain"
|
35
35
|
end
|
36
36
|
```
|
37
37
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Instrumentation
|
2
2
|
|
3
|
-
The [`instrumentation`][instrumentation] plugin
|
4
|
-
operations to a centralized notification component. In addition to that it
|
3
|
+
The [`instrumentation`][instrumentation] plugin publishes events for various
|
4
|
+
operations to a centralized notification component. In addition to that, it
|
5
5
|
provides default logging for these events.
|
6
6
|
|
7
7
|
```rb
|
@@ -40,6 +40,13 @@ Download (1002ms) – {:storage=>:store, :location=>"ed0e30ddec8b97813f2c1f4cfd1
|
|
40
40
|
Delete (700ms) – {:storage=>:store, :location=>"ed0e30ddec8b97813f2c1f4cfd1700b4", :uploader=>Shrine}
|
41
41
|
```
|
42
42
|
|
43
|
+
It uses `Shrine.logger` for logging, which allows you to change where and how
|
44
|
+
are the logs going to be written:
|
45
|
+
|
46
|
+
```rb
|
47
|
+
Shrine.logger = Rails.logger # in Rails apps
|
48
|
+
```
|
49
|
+
|
43
50
|
You can choose to log only certain events, e.g. we can exclude metadata
|
44
51
|
extraction:
|
45
52
|
|
@@ -79,6 +86,7 @@ The following events are instrumented by the `instrumentation` plugin:
|
|
79
86
|
|
80
87
|
* [`upload.shrine`](#uploadshrine)
|
81
88
|
* [`download.shrine`](#downloadshrine)
|
89
|
+
* [`open.shrine`](#openshrine)
|
82
90
|
* [`exists.shrine`](#existsshrine)
|
83
91
|
* [`delete.shrine`](#deleteshrine)
|
84
92
|
* [`metadata.shrine`](#metadatashrine)
|
@@ -94,21 +102,33 @@ following payload:
|
|
94
102
|
| `:location` | The location of the uploaded file |
|
95
103
|
| `:io` | The uploaded IO object |
|
96
104
|
| `:upload_options` | Any upload options that were specified |
|
97
|
-
| `:
|
105
|
+
| `:metadata` | Metadata extracted during upload |
|
106
|
+
| `:options` | Any additional uploader options |
|
98
107
|
| `:uploader` | The uploader class that sent the event |
|
99
108
|
|
100
109
|
### download.shrine
|
101
110
|
|
102
|
-
The `download.shrine` event is logged on `UploadedFile#
|
103
|
-
`UploadedFile#download` and
|
104
|
-
contains the following payload:
|
111
|
+
The `download.shrine` event is logged on `UploadedFile#stream` (which includes
|
112
|
+
`UploadedFile#download`), and contains the following payload:
|
105
113
|
|
106
|
-
| Key
|
107
|
-
| :--
|
108
|
-
| `:storage`
|
109
|
-
| `:location`
|
110
|
-
| `:download_options` | Any
|
111
|
-
| `:uploader`
|
114
|
+
| Key | Description |
|
115
|
+
| :-- | :---- |
|
116
|
+
| `:storage` | The storage identifier |
|
117
|
+
| `:location` | The location of the uploaded file |
|
118
|
+
| `:download_options` | Any download options that were specified |
|
119
|
+
| `:uploader` | The uploader class that sent the event |
|
120
|
+
|
121
|
+
### open.shrine
|
122
|
+
|
123
|
+
The `download.shrine` event is logged on `UploadedFile#open` or when uploaded
|
124
|
+
file is implicitly opened on calling an IO method.
|
125
|
+
|
126
|
+
| Key | Description |
|
127
|
+
| :-- | :---- |
|
128
|
+
| `:storage` | The storage identifier |
|
129
|
+
| `:location` | The location of the uploaded file |
|
130
|
+
| `:download_options` | Any download options that were specified |
|
131
|
+
| `:uploader` | The uploader class that sent the event |
|
112
132
|
|
113
133
|
### exists.shrine
|
114
134
|
|
@@ -141,7 +161,7 @@ following payload:
|
|
141
161
|
| :-- | :---- |
|
142
162
|
| `:storage` | The storage identifier |
|
143
163
|
| `:io` | The uploaded IO object |
|
144
|
-
| `:options` |
|
164
|
+
| `:options` | Any options sent to the uploader |
|
145
165
|
| `:uploader` | The uploader class that sent the event |
|
146
166
|
|
147
167
|
## API
|
data/doc/plugins/keep_files.md
CHANGED
@@ -1,22 +1,12 @@
|
|
1
1
|
# Keep Files
|
2
2
|
|
3
|
-
The [`keep_files`][keep_files] plugin
|
4
|
-
|
5
|
-
|
6
|
-
track history.
|
7
|
-
|
8
|
-
The plugin accepts the following options:
|
9
|
-
|
10
|
-
| Option | Description |
|
11
|
-
| :------ | :---------- |
|
12
|
-
| `:destroyed` | If set to `true`, destroying the record won't delete the associated attachment. |
|
13
|
-
| `:replaced` | If set to `true`, uploading a new attachment won't delete the old one. |
|
14
|
-
|
15
|
-
For example, the following will keep destroyed and replaced files:
|
3
|
+
The [`keep_files`][keep_files] plugin prevents file deletion when the attacher
|
4
|
+
is about to destroy currently attached or previously attached file. This
|
5
|
+
functionality is useful when implementing soft deletes, versioning, or in
|
6
|
+
general any scenario where you need to track history.
|
16
7
|
|
17
8
|
```rb
|
18
|
-
plugin :keep_files
|
9
|
+
plugin :keep_files
|
19
10
|
```
|
20
11
|
|
21
12
|
[keep_files]: /lib/shrine/plugins/keep_files.rb
|
22
|
-
[event store]: http://docs.geteventstore.com/introduction/event-sourcing-basics/
|
@@ -0,0 +1,157 @@
|
|
1
|
+
# Model
|
2
|
+
|
3
|
+
The [`model`][model] plugin provides integration for handling atatchments on
|
4
|
+
mutable structs. It is built on top of the [`entity`][entity] plugin.
|
5
|
+
|
6
|
+
```rb
|
7
|
+
plugin :model
|
8
|
+
```
|
9
|
+
|
10
|
+
## Attachment
|
11
|
+
|
12
|
+
Including a `Shrine::Attachment` module into a model class will, in addition to
|
13
|
+
methods from the `entity` plugin, add the `#<name>=` method for attaching
|
14
|
+
files.
|
15
|
+
|
16
|
+
These methods read and write attachment data to the `#<name>_data` attribute on
|
17
|
+
the model instance.
|
18
|
+
|
19
|
+
```rb
|
20
|
+
class Photo < Model(:image_data)
|
21
|
+
include ImageUploader::Attachment(:image)
|
22
|
+
end
|
23
|
+
```
|
24
|
+
```rb
|
25
|
+
photo = Photo.new
|
26
|
+
photo.image = file
|
27
|
+
photo.image #=> #<ImageUploader::UploadedFile>
|
28
|
+
photo.image_url #=> "https://example.com/foo.jpg"
|
29
|
+
photo.image_attacher #=> #<ImageUploader::Attacher>
|
30
|
+
```
|
31
|
+
|
32
|
+
#### `#<name>=`
|
33
|
+
|
34
|
+
Calls `Attacher#assign` by default, which uploads the file to temporary storage
|
35
|
+
and attaches it, updating the model attribute.
|
36
|
+
|
37
|
+
```rb
|
38
|
+
photo = Photo.new
|
39
|
+
photo.image = file
|
40
|
+
photo.image.storage_key #=> :cache
|
41
|
+
photo.image_data #=> '{"id":"...","storage":"cache","metadata":{...}}'
|
42
|
+
```
|
43
|
+
|
44
|
+
#### Disabling caching
|
45
|
+
|
46
|
+
If you don't want to use temporary storage, you can have `#<name>=` upload
|
47
|
+
directly to permanent storage.
|
48
|
+
|
49
|
+
```rb
|
50
|
+
plugin :model, cache: false
|
51
|
+
```
|
52
|
+
```rb
|
53
|
+
photo = Photo.new
|
54
|
+
photo.image = file
|
55
|
+
photo.image.storage_key #=> :store
|
56
|
+
photo.image_data #=> '{"id":"...","storage":"store","metadata":{...}}'
|
57
|
+
```
|
58
|
+
|
59
|
+
This can be configured on the attacher level as well:
|
60
|
+
|
61
|
+
```rb
|
62
|
+
photo = Photo.new
|
63
|
+
photo.image_attacher(model_cache: false)
|
64
|
+
photo.image = file
|
65
|
+
photo.image.storage_key #=> :store
|
66
|
+
```
|
67
|
+
|
68
|
+
#### `#<name>_attacher`
|
69
|
+
|
70
|
+
Returns an `Attacher` instance backed by the model instance, memoized in an
|
71
|
+
instance variable.
|
72
|
+
|
73
|
+
```rb
|
74
|
+
photo = Photo.new
|
75
|
+
photo.image_attacher #=> #<ImageUploader::Attacher> (memoizes the instance)
|
76
|
+
photo.image_attacher #=> #<ImageUploader::Attacher> (returns memoized instance)
|
77
|
+
```
|
78
|
+
|
79
|
+
When attacher options are passed, the attacher instance is refreshed:
|
80
|
+
|
81
|
+
```rb
|
82
|
+
photo = Photo.new
|
83
|
+
photo.image_attacher(cache: :other_cache)
|
84
|
+
photo.image_attacher.cache_key #=> :other_cache
|
85
|
+
```
|
86
|
+
|
87
|
+
### Entity
|
88
|
+
|
89
|
+
If you still want to include `Shrine::Attachment` modules to immutable
|
90
|
+
entities, you can disable "model" behaviour by passing `type: :entity`:
|
91
|
+
|
92
|
+
```rb
|
93
|
+
class Photo < Entity(:image_data)
|
94
|
+
include ImageUploader::Attachment(:image, type: :entity)
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
## Attacher
|
99
|
+
|
100
|
+
### Loading model
|
101
|
+
|
102
|
+
The `Attacher.from_model` method can be used for creating an `Attacher`
|
103
|
+
instance backed by a model object.
|
104
|
+
|
105
|
+
```rb
|
106
|
+
photo = Photo.new
|
107
|
+
attacher = ImageUploader::Attacher.from_model(photo, :image)
|
108
|
+
|
109
|
+
attacher.record #=> #<Photo>
|
110
|
+
attacher.name #=> :image
|
111
|
+
attacher.attribute #=> :image_data
|
112
|
+
|
113
|
+
attacher.attach(io)
|
114
|
+
photo.image_data #=> '{"id":"...","storage":"...","metadata":{...}}'
|
115
|
+
```
|
116
|
+
|
117
|
+
You can also load an entity into an existing attacher with
|
118
|
+
`Attacher#load_model`.
|
119
|
+
|
120
|
+
```rb
|
121
|
+
photo = Photo.new(image_data: '{"id":"...","storage":"...","metadata":{...}}')
|
122
|
+
attacher = ImageUploader::Attacher.from_model(photo, :image)
|
123
|
+
|
124
|
+
attacher.file #=> nil
|
125
|
+
attacher.load_model(photo, :image)
|
126
|
+
attacher.file #=> #<ImageUploader::UploadedFile>
|
127
|
+
```
|
128
|
+
|
129
|
+
### Writing attachment data
|
130
|
+
|
131
|
+
The `Attacher#write` method writes attachment data to the `#<name>_data`
|
132
|
+
attribute on the model instance.
|
133
|
+
|
134
|
+
```rb
|
135
|
+
photo = Photo.new
|
136
|
+
attacher = ImageUploader::Attacher.from_model(photo, :image)
|
137
|
+
|
138
|
+
attacher.file = uploaded_file
|
139
|
+
photo.image_data #=> nil
|
140
|
+
|
141
|
+
attacher.write
|
142
|
+
photo.image_data #=> '{"id":"...","storage":"...","metadata":{...}}'
|
143
|
+
```
|
144
|
+
|
145
|
+
The `Attacher#write` method is automatically called on `Attacher#set`, as well
|
146
|
+
as `Attacher#assign`, `Attacher#attach_cached`, `Attacher#attach`,
|
147
|
+
`Attacher#promote` and any other attacher method that calls `Attacher#set`.
|
148
|
+
|
149
|
+
## Serialization
|
150
|
+
|
151
|
+
By default, attachment data is serialized into JSON using the `JSON` standard
|
152
|
+
library. If you want to change how data is serialized, see the
|
153
|
+
[`column`][column serializer] plugin docs.
|
154
|
+
|
155
|
+
[model]: /lib/shrine/plugins/model.rb
|
156
|
+
[entity]: /doc/plugins/entity.md#readme
|
157
|
+
[column serializer]: /doc/plugins/column.md#serializer
|