class Elasticsearch::Model::Extensions::Configuration

Attributes

delayed[R]

Public Class Methods

new(active_record_class, parent_class: parent_class, delayed:, only_if: -> r { true } click to toggle source
# File lib/elasticsearch/model/extensions/configuration.rb, line 9
def initialize(active_record_class, parent_class: parent_class, delayed:, only_if: -> r { true }, records_to_update_documents: nil, field_to_update: nil, block: nil)
  @delayed = @delayed

  @active_record_class = active_record_class
  @parent_class = parent_class
  @if = binding.local_variable_get(:only_if)
  @records_to_update_documents = records_to_update_documents
  @field_to_update = field_to_update
  @block = block
end

Public Instance Methods

block() click to toggle source
# File lib/elasticsearch/model/extensions/configuration.rb, line 40
def block
  to_hash[:block]
end
field_to_update() click to toggle source
# File lib/elasticsearch/model/extensions/configuration.rb, line 24
def field_to_update
  to_hash[:field_to_update]
end
has_dependent_fields?() click to toggle source

@return [Boolean]

# File lib/elasticsearch/model/extensions/configuration.rb, line 51
def has_dependent_fields?
  @has_dependent_fields
end
index_update_required?(record) click to toggle source

@param [ActiveRecord::Base] record the updated record we are unsure whether it must be also updated in elasticsearch or not @return [Boolean] true if we have to update the document for the record indexed in Elasticsearch

# File lib/elasticsearch/model/extensions/configuration.rb, line 58
def index_update_required?(record)
  previous_changes = record.previous_changes

  defined?(record.index_update_required?) && record.index_update_required? ||
    (previous_changes.keys & nested_object_fields).size > 0 ||
    (previous_changes.size > 0 && has_dependent_fields?)
end
nested_object_fields() click to toggle source

TODO Document what is in the Array @return [Array]

# File lib/elasticsearch/model/extensions/configuration.rb, line 46
def nested_object_fields
  @nested_object_fields
end
only_if() click to toggle source
# File lib/elasticsearch/model/extensions/configuration.rb, line 28
def only_if
  to_hash[:only_if]
end
optionally_delayed() click to toggle source
# File lib/elasticsearch/model/extensions/configuration.rb, line 36
def optionally_delayed
  -> t { delayed ? t.delay : t }
end
records_to_update_documents() click to toggle source
# File lib/elasticsearch/model/extensions/configuration.rb, line 32
def records_to_update_documents
  to_hash[:records_to_update_documents]
end
to_hash() click to toggle source
# File lib/elasticsearch/model/extensions/configuration.rb, line 20
def to_hash
  @cached_hash ||= build_hash
end

Private Instance Methods

association_path_finder() click to toggle source

@return [Elasticsearch::Model::Extensions::AssociationPathFinding::AssociationPathFinder]

# File lib/elasticsearch/model/extensions/configuration.rb, line 69
def association_path_finder
  @association_path_finder ||= Elasticsearch::Model::Extensions::AssociationPathFinding::AssociationPathFinder.new
end
build_hash() click to toggle source
# File lib/elasticsearch/model/extensions/configuration.rb, line 100
def build_hash
  child_class = @active_record_class

  field_to_update = provided_field_to_update
  parent_to_child_path = provided_parent_to_child_path

  puts "#{child_class.name} updates #{@parent_class.name}'s #{field_to_update}"

  @nested_object_fields = @parent_class.__mapping_reflector__.nested_object_fields_for(parent_to_child_path).map(&:to_s)
  @has_dependent_fields = @parent_class.__dependency_tracker__.has_dependent_fields?(field_to_update) ||
    (@calculated_path && @calculated_path.first.destination.through_class == child_class && @parent_class.__dependency_tracker__.has_association_named?(field_to_update) && @parent_class.__mapping_reflector__.has_document_field_named?(field_to_update))

  custom_if = @if

  update_strategy_class = Elasticsearch::Model::Extensions::OuterDocumentUpdating.strategy_for child_class
  update_strategy = update_strategy_class.new(from: @parent_class, to: child_class)

  only_if, records_to_update_documents = update_strategy.apply

  # The default block used to trigger partial updating on the parent document.
  # Replace this by specifying `block` parameter to a configuration like `Configuration.new(block: BLOCK)`
  # when more fine-grained controls over it like feature-toggling, graceful-degradation are required.
  default_partial_updating_block = -> t, field_to_update {
    t.partially_update_document(field_to_update)
  }

  {
    field_to_update: field_to_update,
    records_to_update_documents: @records_to_update_documents || records_to_update_documents,
    only_if: -> r { custom_if.call(r) && only_if.call(r) },
    block: @block || default_partial_updating_block
  }
end
extract_path_from_hash(hash) click to toggle source
# File lib/elasticsearch/model/extensions/configuration.rb, line 89
def extract_path_from_hash(hash)
  hash.is_a?(Symbol) ? [hash] : (hash.keys.empty? ? [] : [hash.keys.first] + extract_path_from_hash(hash[hash.keys.first]))
end
provided_field_to_update() click to toggle source
# File lib/elasticsearch/model/extensions/configuration.rb, line 93
def provided_field_to_update
  # a has_a b has_a cという関係のとき、cが更新されたらaのフィールドbをupdateする必要がある。
  # そのとき、
  # 親aから子cへのパスが[:b, :c]だったら、bだけをupdateすればよいので
  provided_parent_to_child_path.first
end
provided_parent_to_child_path() click to toggle source
# File lib/elasticsearch/model/extensions/configuration.rb, line 73
def provided_parent_to_child_path
  field_to_update = @field_to_update

  @parent_to_child_path ||=
      if field_to_update.is_a? Hash
        extract_path_from_hash(field_to_update)
      elsif field_to_update.is_a? Symbol
        [field_to_update]
      elsif field_to_update.nil?
        @calculated_path = association_path_finder.find_path(from: @parent_class, to: @active_record_class)
        @calculated_path.map(&:name)
      else
        raise "Unexpected type for field_to_update: #{field_to_update}(#{field_to_update.class})"
      end
end