lib/garner/mixins/mongoid/document.rb
module Garner
module Mixins
module Mongoid
module Document
extend ActiveSupport::Concern
include Garner::Cache::Binding
def proxied_classes
self.class.mongoid_superclasses
end
def identity_string
"#{self.class.name}/id=#{id}"
end
included do
extend Garner::Cache::Binding
# Return an array of this class and all Mongoid superclasses.
#
# @return [Array] An array of classes.
def self.mongoid_superclasses
if superclass.include?(Mongoid::Document)
[self] + superclass.mongoid_superclasses
else
[self]
end
end
# Return an object that can act as a binding on this class's behalf.
#
# @return [Mongoid::Document]
def self.proxy_binding
_latest_by_updated_at
end
def self.identify(handle)
Mongoid::Identity.from_class_and_handle(self, handle)
end
# Find an object by _id, or other findable field, or by multiple findable
# fields, first trying to fetch from Garner's cache.
#
#
# @example Find by an id.
# Garner::Mixins::Mongoid::Document.garnered_find(BSON::ObjectId.new)
#
# @example Find by multiple id's.
# Garner::Mixins::Mongoid::Document.garnered_find(BSON::ObjectId.new, BSON::ObjectId.new)
#
# @example Find by multiple id's in an array.
# Garner::Mixins::Mongoid::Document.garnered_find([ BSON::ObjectId.new, BSON::ObjectId.new ])
#
# @return [ Array<Mongoid::Document>, Mongoid::Document ]
def self.garnered_find(*args)
identity = Garner::Cache::Identity.new
args.flatten.each do |arg|
binding = identify(arg)
identity = identity.bind(binding)
end
identity.key(garnered_find_args: args) do
find(*args)
end
end
after_create :_garner_after_create
after_update :_garner_after_update
after_destroy :_garner_after_destroy
protected
def self._latest_by_updated_at
# Only find the latest if we can order by :updated_at
return nil unless fields['updated_at']
only(:_id, :_type, :updated_at).order_by(updated_at: :desc).first
end
def _invalidate
invalidation_strategy.apply(self)
invalidation_strategy.apply(_root) if _root != self && Garner.config.invalidate_mongoid_root
end
end
end
end
end
end