Module: Elasticsearch::Model::Extensions::PartialUpdating

Defined in:
lib/elasticsearch/model/extensions/partial_updating.rb

Defined Under Namespace

Modules: Callbacks, ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.build_as_json_options(klass:, props:) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/elasticsearch/model/extensions/partial_updating.rb', line 9

def self.build_as_json_options(klass:, props: )
  indexed_attributes = props.keys
  associations = klass.reflect_on_all_associations.select { |a| %i| has_one has_many belongs_to |.include? a.macro }
  association_names = associations.map(&:name)
  persisted_attributes = klass.attribute_names.map(&:intern)

  nested_attributes = indexed_attributes & association_names
  method_attributes = indexed_attributes - persisted_attributes - nested_attributes
  only_attributes = indexed_attributes - nested_attributes

  options = {
    root: false
  }

  if only_attributes.size > 1
    options[:only] = only_attributes
  elsif only_attributes.size == 1
    options[:only] = only_attributes.first
  end

  if method_attributes.size > 1
    options[:methods] = method_attributes
  elsif method_attributes.size == 1
    options[:methods] = method_attributes.first
  end

  nested_attributes.each do |n|
    a = associations.find { |a| a.name == n.intern }
    nested_klass = a.class_name.constantize
    nested_prop = props[n]
    if nested_prop.present?
      options[:include] ||= {}
      options[:include][n] = build_as_json_options(
        klass: nested_klass,
        props: nested_prop[:properties]
      )
    end
  end

  options
end

.included(klass) ⇒ Object



5
6
7
# File 'lib/elasticsearch/model/extensions/partial_updating.rb', line 5

def self.included(klass)
  klass.extend ClassMethods
end

Instance Method Details

#as_indexed_json(options = {}) ⇒ Object



51
52
53
# File 'lib/elasticsearch/model/extensions/partial_updating.rb', line 51

def as_indexed_json(options={})
  as_json(options.merge(self.class.as_json_options))
end

#build_partial_document_for_update(*changed_attributes, json_options: nil) ⇒ Object

Parameters:

  • changed_attributes (Array<Symbol>)
  • json_options (Proc<Symbol, Hash>) (defaults to: nil)


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/elasticsearch/model/extensions/partial_updating.rb', line 57

def build_partial_document_for_update(*changed_attributes, json_options: nil)
  changes = {}

  json_options ||= -> field { self.class.partial_as_json_options(field) || {} }

  self.class.each_field_to_update_according_to_changed_fields(changed_attributes) do |field_to_update|
    options = json_options.call field_to_update

    json = __send__(:"#{field_to_update}").as_json(options)

    changes[field_to_update] = json
  end

  changes
end

#partially_update_document(*changed_attributes) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/elasticsearch/model/extensions/partial_updating.rb', line 73

def partially_update_document(*changed_attributes)
  if changed_attributes.empty?
    __elasticsearch__.index_document
  else
    begin
      partial_document = build_partial_document_for_update(*changed_attributes)
    rescue => e
      if defined? ::Rails
        ::Rails.logger.error "Error in #partially_update_document: #{e.message}\n#{e.backtrace.join("\n")}"
      else
        warn "Error in #partially_update_document: #{e.message}\n#{e.backtrace.join("\n")}"
      end
    end

    update_document(partial_document)
  end
end

#update_document(partial_document) ⇒ Object

Parameters:

  • partial_document (Hash)


92
93
94
95
96
97
98
99
100
101
# File 'lib/elasticsearch/model/extensions/partial_updating.rb', line 92

def update_document(partial_document)
  klass = self.class

  __elasticsearch__.client.update(
    { index: klass.index_name,
      type:  klass.document_type,
      id:    self.id,
      body:  { doc: partial_document } }
  ) if partial_document.size > 0
end