Writing a Persistence Plugin
This guide explains some conventions for writing Shrine plugins that integrate with persistence libraries such as Active Record, Sequel, ROM and Mongoid. It assumes you've read the Writing a Plugin guide.
Let's say we're writing a plugin for a persistence library called "Raptor":
# lib/shrine/plugins/raptor.rb
require "raptor"
class Shrine
module Plugins
module Raptor
# ...
end
register_plugin(:raptor, Raptor)
end
end
Attachment
If your database library uses the Active Record pattern, it's recommended to
load the model
plugin as a dependency.
module Shrine::Plugins::Raptor
def self.load_dependencies(uploader, **)
uploader.plugin :model # for Active Record pattern
end
# ...
end
Otherwise if it uses the Repository pattern, you can load the
entity
plugin as a dependency.
module Shrine::Plugins::Raptor
def self.load_dependencies(uploader, **)
uploader.plugin :entity # for Repository pattern
end
# ...
end
If you want to add library-specific integration when Shrine::Attachment
is
included into a model/entity, it's recommended to do this in the included
hook, so that you can perform this logic only for models/entities that belong
to that persistence library.
module Shrine::Plugins::Raptor
# ...
module AttachmentMethods
def included(klass)
super
return unless klass < ::Raptor::Model
# library specific integration
end
end
# ...
end
Attacher
To help define persistence methods on the Attacher
according to the
convention, load the _persistence
plugin as a dependency:
module Shrine::Plugins::Raptor
def self.load_dependencies(uploader, **)
# ...
uploader.plugin :_persistence, plugin: self
end
# ...
end
This will define the following attacher methods:
Attacher#persist
Attacher#atomic_persist
Attacher#atomic_promote
For those methods to work, we'll need to implement the following methods:
Attacher#<library>_persist
Attacher#<library>_reload
Attacher#<library>?
module Shrine::Plugins::Raptor
# ...
module AttacherMethods
# ...
private
def raptor_persist
# persist attached file to the record
end
def raptor_reload
# yield reloaded record (see atomic_helpers plugin)
end
def raptor?
# returns whether current model/entity belongs to Raptor
end
end
end