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.

[View source]

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__`

[View source]

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.

[View source]

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

def initialize_dup(_)
  @__elasticsearch__ = nil
  super
end