Sequel
The sequel
plugin adds Sequel integration to the attachment
interface. It is built on top of the model
plugin.
Shrine.plugin :sequel
Attachment
Including a Shrine::Attachment
module into a Sequel::Model
subclass will:
- add model attachment methods
- add validations and hooks to tie attachment process to the record lifecycle
# has `image_data` column include ImageUploader::Attachment(:image) # adds methods, callbacks & validations end
photo = Photo.new photo.image = file # cache attachment photo.image #=> #<Shrine::UploadedFile id="bc2e13.jpg" storage=:cache ...> photo.image_data #=> '{"id":"bc2e13.jpg","storage":"cache","metadata":{...}}' photo.save # persist, promote attachment, then persist again photo.image #=> #<Shrine::UploadedFile id="397eca.jpg" storage=:store ...> photo.image_data #=> '{"id":"397eca.jpg","storage":"store","metadata":{...}}' photo.destroy # delete attachment photo.image.exists? #=> false
Hooks
After Save
After a record is saved and the transaction is committed, Attacher#finalize
is called, which promotes cached file to permanent storage and deletes previous
file if any.
photo = Photo.new photo.image = filephoto.image.storage_key #=> :cache photo.savephoto.image.storage_key #=> :store
After Destroy
After a record is destroyed and the transaction is committed,
Attacher#destroy_attached
method is called, which deletes stored attached
file if any.
photo = Photo.find(photo_id)photo.image #=> #<Shrine::UploadedFile> photo.image.exists? #=> true photo.destroyphoto.image.exists? #=> false
Overriding hooks
You can override any of the following attacher methods to modify callback behaviour:
Attacher#sequel_before_save
Attacher#sequel_after_save
Attacher#sequel_after_destroy
super # ... endend
Skipping Hooks
If you don't want the attachment module to add any hooks to your model, you can
set :hooks
to false
:
plugin :sequel, hooks: false
Validations
If you're using the validation
plugin, the attachment module
will automatically merge attacher errors with model errors.
plugin :validation_helpers Attacher.validate do validate_max_size 10 * 1024 * 1024 endend
photo = Photo.newphoto.image = filephoto.valid?photo.errors #=> { image: ["size must not be greater than 10.0 MB"] }
Attachment Presence
If you want to validate presence of the attachment, you can use Sequel's presence validator:
include ImageUploader::Attachment(:image) super validates_presence :image endend
Skipping Validations
If don't want the attachment module to merge file validations errors into
model errors, you can set :validations
to false
:
plugin :sequel, validations: false
Attacher
You can also use Shrine::Attacher
directly (with or without the
Shrine::Attachment
module):
# has `image_data` column end
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":{...}}' photo.save # persist attacher.finalize # promote photo.save # persist attacher.file #=> #<Shrine::UploadedFile id="397eca.jpg" storage=:store ...> photo.image_data #=> '{"id":"397eca.jpg","storage":"store","metadata":{...}}'
Persistence
The following persistence methods are added to Shrine::Attacher
:
Method | Description |
---|---|
Attacher#atomic_promote | calls Attacher#promote and persists if the attachment hasn't changed |
Attacher#atomic_persist | saves changes if the attachment hasn't changed |
Attacher#persist | saves any changes to the underlying record |
See persistence docs for more details.