module Elasticsearch::Model::Proxy
This module provides a proxy interfacing between the including class and `Elasticsearch::Model`, preventing the pollution of the including class namespace.
The only “gateway” between the model and Elasticsearch::Model
is the `#__elasticsearch__` class and instance method.
The including class must be compatible with [ActiveModel](github.com/rails/rails/tree/master/activemodel).
@example Include the `Elasticsearch::Model` module into an `Article` model
class Article < ActiveRecord::Base include Elasticsearch::Model end Article.__elasticsearch__.respond_to?(:search) # => true article = Article.first article.respond_to? :index_document # => false article.__elasticsearch__.respond_to?(:index_document) # => true
Public Class Methods
`ClassMethodsProxy` instance, accessed as `MyModel.__elasticsearch__`
# File lib/elasticsearch/model/proxy.rb, line 60 def self.__elasticsearch__ &block @__elasticsearch__ ||= ClassMethodsProxy.new(self) @__elasticsearch__.instance_eval(&block) if block_given? @__elasticsearch__ end
Define the `__elasticsearch__` class and instance methods in the including class and register a callback for intercepting changes in the model.
@note The callback is triggered only when `Elasticsearch::Model` is included in the
module and the functionality is accessible via the proxy.
# File lib/elasticsearch/model/proxy.rb, line 55 def self.included(base) base.class_eval do # `ClassMethodsProxy` instance, accessed as `MyModel.__elasticsearch__` def self.__elasticsearch__ &block @__elasticsearch__ ||= ClassMethodsProxy.new(self) @__elasticsearch__.instance_eval(&block) if block_given? @__elasticsearch__ end # Mix the importing module into the `ClassMethodsProxy` self.__elasticsearch__.class_eval do include Adapter.from_class(base).importing_mixin end # Register a callback for storing changed attributes for models which implement # `before_save` method and return changed attributes (ie. when `Elasticsearch::Model` is included) # # @see http://api.rubyonrails.org/classes/ActiveModel/Dirty.html # before_save do |obj| if obj.respond_to?(:changes_to_save) # Rails 5.1 changes_to_save = obj.changes_to_save elsif obj.respond_to?(:changes) changes_to_save = obj.changes end if changes_to_save attrs = obj.__elasticsearch__.instance_variable_get(:@__changed_model_attributes) || {} latest_changes = changes_to_save.inject({}) { |latest_changes, (k,v)| latest_changes.merge!(k => v.last) } obj.__elasticsearch__.instance_variable_set(:@__changed_model_attributes, attrs.merge(latest_changes)) end end if respond_to?(:before_save) end # {InstanceMethodsProxy}, accessed as `@mymodel.__elasticsearch__` # def __elasticsearch__ &block @__elasticsearch__ ||= InstanceMethodsProxy.new(self) @__elasticsearch__.instance_eval(&block) if block_given? @__elasticsearch__ end end
Public Instance Methods
{InstanceMethodsProxy}, accessed as `@mymodel.__elasticsearch__`
# File lib/elasticsearch/model/proxy.rb, line 93 def __elasticsearch__ &block @__elasticsearch__ ||= InstanceMethodsProxy.new(self) @__elasticsearch__.instance_eval(&block) if block_given? @__elasticsearch__ end
@overload dup
Returns a copy of this object. Resets the __elasticsearch__ proxy so the duplicate will build its own proxy.
# File lib/elasticsearch/model/proxy.rb, line 104 def initialize_dup(_) @__elasticsearch__ = nil super end