Model
The model
plugin provides integration for handling attachment on
mutable structs. It is built on top of the entity
plugin.
plugin :model
Attachment
Including a Shrine::Attachment
module into a model class will:
- add entity attachment methods
- add
#<name>=
and#<name>_changed?
methods
attr_accessor :image_data include ImageUploader::Attachment(:image)end
photo = Photo.new photo.image = file photo.image #=> #<Shrine::UploadedFile id="bc2e13.jpg" storage=:cache ...> photo.image_data #=> '{"id":"bc2e13.jpg","storage":"cache","metadata":{...}}' photo.image_attacher.finalize photo.image #=> #<Shrine::UploadedFile id="397eca.jpg" storage=:store ...> photo.image_data #=> '{"id":"397eca.jpg","storage":"store","metadata":{...}}'
#<name>=
Calls Attacher#assign
by default, which uploads the file to temporary storage
and attaches it, updating the model attribute.
photo = Photo.newphoto.image = filephoto.image.storage_key #=> :cache photo.image_data #=> '{"id":"...","storage":"cache","metadata":{...}}'
#<name>_changed?
Calls Attacher#changed?
which returns whether the attachment has changed.
photo = Photo.newphoto.image_changed? #=> false photo.image = filephoto.image_changed? #=> true
Disabling caching
If you don't want to use temporary storage, you can have #<name>=
upload
directly to permanent storage.
plugin :model, cache: false
photo = Photo.newphoto.image = filephoto.image.storage_key #=> :store photo.image_data #=> '{"id":"...","storage":"store","metadata":{...}}'
This can be configured on the attacher level as well:
photo = Photo.newphoto.image_attacher(model_cache: false)photo.image = filephoto.image.storage_key #=> :store
#<name>_attacher
Returns an Attacher
instance backed by the model instance, memoized in an
instance variable.
photo = Photo.newphoto.image_attacher #=> #<ImageUploader::Attacher> (memoizes the instance) photo.image_attacher #=> #<ImageUploader::Attacher> (returns memoized instance)
When attacher options are passed, the attacher instance is refreshed:
photo = Photo.newphoto.image_attacher(cache: :other_cache)photo.image_attacher.cache_key #=> :other_cache
Entity
If you still want to include Shrine::Attachment
modules to immutable
entities, you can disable "model" behaviour by passing model: false
:
attr_reader :image_data include ImageUploader::Attachment(:image, model: false)end
Attacher
You can also use Shrine::Attacher
directly (with or without the
Shrine::Attachment
module):
attr_accessor :image_dataend
photo = Photo.newattacher = ImageUploader::Attacher.from_model(photo, :image) attacher.assign(file) # cache attacher.file #=> #<Shrine::UploadedFile id="bc2e13.jpg" storage=:cache ...> photo.image_data #=> '{"id":"bc2e13.jpg","storage":"cache","metadata":{...}}' attacher.finalize # promote attacher.file #=> #<Shrine::UploadedFile id="397eca.jpg" storage=:store ...> photo.image_data #=> '{"id":"397eca.jpg","storage":"store","metadata":{...}}'
Loading model
The Attacher.from_model
method can be used for creating an Attacher
instance backed by a model object.
photo = Photo.newattacher = ImageUploader::Attacher.from_model(photo, :image) attacher.record #=> #<Photo> attacher.name #=> :image attacher.attribute #=> :image_data attacher.attach(io)photo.image_data #=> '{"id":"...","storage":"...","metadata":{...}}'
You can also load an entity into an existing attacher with
Attacher#load_model
.
photo = Photo.new(image_data: '{"id":"...","storage":"...","metadata":{...}}') attacher.file #=> nil attacher.load_model(photo, :image)attacher.file #=> #<ImageUploader::UploadedFile>
Or just Attacher#set_model
if you don't want to load attachment data:
photo = Photo.new(image_data: '{"id":"...","storage":"...","metadata":{...}}') attacher.file #=> nil attacher.set_model(photo, :image) # doesn't load attachment data attacher.file #=> nil
Writing attachment data
The Attacher#write
method writes attachment data to the #<name>_data
attribute on the model instance.
photo = Photo.newattacher = ImageUploader::Attacher.from_model(photo, :image) attacher.file = uploaded_filephoto.image_data #=> nil attacher.writephoto.image_data #=> '{"id":"...","storage":"...","metadata":{...}}'
The Attacher#write
method is automatically called on Attacher#set
, as well
as Attacher#assign
, Attacher#attach_cached
, Attacher#attach
,
Attacher#promote
and any other attacher method that calls Attacher#set
.
Serialization
By default, attachment data is serialized into JSON using the JSON
standard
library. If you want to change how data is serialized, see the
column
plugin docs.