Entity
The entity
plugin provides integration for handling attachments on
immutable structs. It is built on top of the column
plugin.
plugin :entity
Attachment
Including a Shrine::Attachment
module into an entity class will add the
following instance methods:
#<name>
– returns the attached file#<name>_url
– returns the attached file URL#<name>_attacher
– returns aShrine::Attacher
instance
These methods read attachment data from the #<name>_data
attribute on the
entity instance.
class Photo
attr_reader :image_data
include ImageUploader::Attachment(:image)
end
photo = Photo.new(image_data: '{"id":"...","storage":"...","metadata":{...}}')
photo.image #=> #<ImageUploader::UploadedFile>
photo.image_url #=> "https://example.com/image.jpg"
photo.image_attacher #=> #<ImageUploader::Attacher>
#<name>
Calls Attacher#get
, which returns an UploadedFile
object instantiated from
attachment data.
photo = Photo.new(image_data: '{"id":"foo.jpg","storage":"store","metadata":{...}}')
photo.image #=> #<ImageUploader::UploadedFile>
photo.image.id #=> "foo.jpg"
photo.image.storage_key #=> :store
photo.image.metadata #=> { ... }
If no file is attached, nil
is returned.
photo = Photo.new(image_data: nil)
photo.image #=> nil
#<name>_url
Calls Attacher#url
, which returns the URL to the attached file.
photo = Photo.new(image_data: {"id":"foo.jpg","storage":"...","metadata":{...}})
photo.image_url #=> "https://example.com/foo.jpg"
If no file is attached, nil
is returned.
photo = Photo.new(image_data: nil)
photo.image_url #=> nil
#<name>_attacher
Calls Attacher.from_entity
, which returns an Attacher
instance backed by
the entity object.
photo = Photo.new
photo.image_attacher #=> #<ImageUploader::Attacher>
photo.image_attacher.record #=> #<Photo>
photo.image_attacher.name #=> :image
photo.image_attacher.attribute #=> :image_data
Any additional options will be forwarded to Attacher#initialize
.
photo = Photo.new
attacher = photo.image_attacher(cache: :other_cache)
attacher.cache_key #=> :other_cache
You can also specify default attacher options when including
Shrine::Attachment
:
class Photo
attr_reader :image_data
include ImageUploader::Attachment(:image, store: :other_store)
end
photo = Photo.new
attacher = photo.image_attacher
attacher.store_key #=> :other_store
You can retrieve an Attacher
instance from the entity class as well. In
this case it will not be initialized with any entity instance.
attacher = Photo.image_attacher
attacher #=> #<ImageUploader::Attacher>
attacher.record #=> nil
attacher.name #=> nil
attacher = Photo.image_attacher(store: :other_store)
attacher.store_key #=> :other_store
Attacher
You can also use Shrine::Attacher
directly (with or without the
Shrine::Attachment
module):
class Photo
attr_reader :image_data
end
photo = Photo.new(image_data: '{"id":"...","storage":"...","metadata":{...}}')
attacher = ImageUploader::Attacher.from_entity(photo, :image)
attacher.file #=> #<Shrine::UploadedFile id="bc2e13.jpg" storage=:store ...>
attacher.attach(file)
attacher.file #=> #<Shrine::UploadedFile id="397eca.jpg" storage=:store ...>
attacher.column_values #=> { image_data: '{"id":"397eca.jpg","storage":"store","metadata":{...}}' }
photo = Photo.new(attacher.column_values)
attacher = ImageUploader::Attacher.from_entity(photo, :image)
attacher.file #=> #<Shrine::UploadedFile id="397eca.jpg" storage=:store ...>
Loading entity
The Attacher.from_entity
method can be used for creating an Attacher
instance backed by an entity object.
photo = Photo.new(image_data: '{"id":"...","storage":"...","metadata":{...}}')
attacher = ImageUploader::Attacher.from_entity(photo, :image)
attacher.record #=> #<Photo>
attacher.name #=> :image
attacher.attribute #=> :image_data
attacher.file #=> #<ImageUploader::UploadedFile>
Any additional options are forwarded to Attacher#initialize
.
attacher = ImageUploader::Attacher.from_entity(photo, :image, cache: :other_cache)
attacher.cache_key #=> :other_cache
You can also load an entity into an existing attacher with
Attacher#load_entity
.
photo = Photo.new(image_data: '{"id":"...","storage":"...","metadata":{...}}')
attacher.load_entity(photo, :image)
attacher.record #=> #<Photo>
attacher.name #=> :image
attacher.file #=> #<ImageUploader::UploadedFile>
Or just Attacher#set_entity
if you don't want to load attachment data:
photo = Photo.new(image_data: '{"id":"...","storage":"...","metadata":{...}}')
attacher.set_entity(photo, :image) # doesn't load attachment data
attacher.record #=> #<Photo>
attacher.name #=> :image
attacher.file #=> nil
Reloading
The Attacher#reload
method reloads attached file from the attachment data on
the entity attribute and resets dirty tracking.
photo = Photo.new
attacher = ImageUploader::Attacher.from_entity(photo, :image)
attacher.file #=> nil
photo.image_data = '{"id":"...","storage":"...","metadata":{...}}'
attacher.file #=> nil
attacher.reload
attacher.file #=> #<ImageUploader::UploadedFile>
If you want to reload attachment data while retaining dirty tracking state, use
Attacher#read
instead.
Column values
The Attacher#column_values
method returns a hash with the entity attribute as
key and current attachment data as value.
attacher = ImageUploader::Attacher.from_entity(Photo.new, :image)
attacher.attach(io)
attacher.column_values #=> { :image_data => '{"id":"...","storage":"...","metadata":{...}}' }
The Attacher#attribute
method returns just the entity attribute from which
attached file data is read.
attacher = ImageUploader::Attacher.from_entity(Photo.new, :image)
attacher.attribute #=> :image_data
Entity data
The Attacher#record
method returns the entity instance from which the
attacher was loaded.
attacher = ImageUploader::Attacher.from_entity(Photo.new, :image)
attacher.record #=> #<Photo>
The Attacher#name
method returns the name of the attachment from which the
attacher was loaded.
attacher = ImageUploader::Attacher.from_entity(Photo.new, :image)
attacher.name #=> :image
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.