lib/garner/mixins/mongoid/identity.rb
module Garner
module Mixins
module Mongoid
class Identity
include Garner::Cache::Binding
attr_accessor :klass, :handle, :proxy_binding, :conditions
# Instantiate a new Mongoid::Identity.
#
# @param klass [Class] A
# @param handle [Object] A String, Fixnum, BSON::ObjectId, etc.
# identifying the object.
# @return [Garner::Mixins::Mongoid::Identity]
def self.from_class_and_handle(klass, handle)
validate_class!(klass)
new.tap do |identity|
identity.klass = klass
identity.handle = handle
identity.conditions = conditions_for(klass, handle)
end
end
def initialize
@conditions = {}
end
# Return an object that can act as a binding on this identity's behalf.
#
# @return [Mongoid::Document]
def proxy_binding
return nil unless handle
@proxy_binding ||= klass.where(conditions).only(:_id, :_type, :updated_at).limit(1).entries.first
end
# Stringize this identity for purposes of marshaling.
#
# @return [String]
def to_s
"#{self.class.name}/klass=#{klass},handle=#{handle}"
end
def self.validate_class!(klass)
if !klass.include?(::Mongoid::Document)
fail 'Must instantiate from a Mongoid class'
elsif klass.embedded?
fail 'Cannot instantiate from an embedded document class'
end
end
def self.conditions_for(klass, handle)
# Multiple-ID conditions
conditions = {
'$or' => Garner.config.mongoid_identity_fields.map do |field|
{ field => handle }
end
}
# _type conditions
selector = klass.where({})
conditions.merge!(selector.send(:type_selection)) if selector.send(:type_selectable?)
conditions
end
end
end
end
end