Shrine

Shrine

  • Guides
  • Plugins
  • External
  • Discourse
  • GitHub
  • Wiki

›Attachment

Attachment

  • Active Record
  • Column
  • Entity
  • Model
  • Sequel

Flow

  • Backgrounding
  • Presign Endpoint
  • Upload Endpoint

Processing

  • Derivation Endpoint
  • Derivatives

Source

  • Data URI
  • Rack File
  • Remote URL

Validation

  • Remove Invalid
  • Validation
  • Validation Helpers

Metadata

  • Add Metadata
  • Determine MIME Type
  • Infer Extension
  • Metadata Attributes
  • Refresh Metadata
  • Restore Cached Data
  • Signature
  • Store Dimensions
  • Type Predicates

Downloading

  • Download Endpoint
  • Rack Response
  • Tempfile

Form

  • Cached Attachment Data
  • Form Assign
  • Remove Attachment

Settings

  • Default Storage
  • Default URL
  • Dynamic Storage
  • Multi Cache
  • Pretty Location
  • Upload Options
  • URL Options

Other

  • Atomic Helpers
  • Included
  • Instrumentation
  • Keep Files
  • Mirroring
Edit

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
class Photo
  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.new
photo.image = file
photo.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.new
photo.image_changed? #=> false 
photo.image = file
photo.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.new
photo.image = file
photo.image.storage_key #=> :store 
photo.image_data        #=> '{"id":"...","storage":"store","metadata":{...}}' 

This can be configured on the attacher level as well:

photo = Photo.new
photo.image_attacher(model_cache: false)
photo.image = file
photo.image.storage_key #=> :store 

#<name>_attacher

Returns an Attacher instance backed by the model instance, memoized in an instance variable.

photo = Photo.new
photo.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.new
photo.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:

class Photo
  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):

class Photo
  attr_accessor :image_data
end
photo    = Photo.new
attacher = 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.new
attacher = 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.new
attacher = ImageUploader::Attacher.from_model(photo, :image)
 
attacher.file = uploaded_file
photo.image_data #=> nil 
 
attacher.write
photo.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.

← EntitySequel →
  • Attachment
    • Entity
  • Attacher
    • Loading model
    • Writing attachment data
  • Serialization
Shrine
Docs
GuidesPluginsExternalContributing
Community
DiscourseStack Overflow
More
BlogGitHubStar
Follow @shrine_rb
Copyright © 2022 Janko Marohnić