Module: Elasticsearch::Model::Proxy

Defined in:
lib/elasticsearch/model/proxy.rb

Overview

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).

Examples:

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

Defined Under Namespace

Modules: Base Classes: ClassMethodsProxy, InstanceMethodsProxy

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object

Note:

The callback is triggered only when ‘Elasticsearch::Model` is included in the module and the functionality is accessible via the proxy.

Define the ‘__elasticsearch__` class and instance methods in the including class and register a callback for intercepting changes in the model.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/elasticsearch/model/proxy.rb', line 53

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

Instance Method Details

#__elasticsearch__(&block) ⇒ Object

InstanceMethodsProxy, accessed as ‘@mymodel.__elasticsearch__`



89
90
91
92
93
# File 'lib/elasticsearch/model/proxy.rb', line 89

def __elasticsearch__ &block
  @__elasticsearch__ ||= InstanceMethodsProxy.new(self)
  @__elasticsearch__.instance_eval(&block) if block_given?
  @__elasticsearch__
end

#dupObject

Returns a copy of this object. Resets the __elasticsearch__ proxy so the duplicate will build its own proxy.



100
101
102
103
# File 'lib/elasticsearch/model/proxy.rb', line 100

def initialize_dup(_)
  @__elasticsearch__ = nil
  super
end