class Chewy::Fields::Base

Attributes

children[R]
join_options[R]
name[R]
options[R]
parent[RW]

Public Class Methods

new(name, value: nil, **options) click to toggle source
# File lib/chewy/fields/base.rb, line 7
def initialize(name, value: nil, **options)
  @name = name.to_sym
  @options = {}
  update_options!(**options)
  @value = value
  @children = []
  @allowed_relations = find_allowed_relations(options[:relations]) # for join fields
end

Public Instance Methods

compose(*objects) click to toggle source
# File lib/chewy/fields/base.rb, line 42
def compose(*objects)
  result = evaluate(objects)

  return {} if result.blank? && ignore_blank?

  if children.present? && !multi_field?
    result = if result.respond_to?(:to_ary)
      result.to_ary.map { |item| compose_children(item, *objects) }
    else
      compose_children(result, *objects)
    end
  end

  {name => result}
end
mappings_hash() click to toggle source
# File lib/chewy/fields/base.rb, line 29
def mappings_hash
  mapping =
    if children.present?
      {(multi_field? ? :fields : :properties) => children.map(&:mappings_hash).inject(:merge)}
    else
      {}
    end
  mapping.reverse_merge!(options.except(:ignore_blank))
  mapping.reverse_merge!(type: (children.present? ? 'object' : Chewy.default_field_type))

  {name => mapping}
end
multi_field?() click to toggle source
# File lib/chewy/fields/base.rb, line 21
def multi_field?
  children.present? && !object_field?
end
object_field?() click to toggle source
# File lib/chewy/fields/base.rb, line 25
def object_field?
  (children.present? && options[:type].blank?) || %w[object nested].include?(options[:type].to_s)
end
update_options!(**options) click to toggle source
# File lib/chewy/fields/base.rb, line 16
def update_options!(**options)
  @join_options = options.delete(:join) || {}
  @options = options
end
value() click to toggle source
# File lib/chewy/fields/base.rb, line 58
def value
  if join_field?
    join_type = join_options[:type]
    join_id = join_options[:id]
    # memoize
    @value ||= proc do |object|
      validate_join_type!(value_by_name_proc(join_type).call(object))
      # If it's a join field and it has join_id, the value is compound and contains
      # both name (type) and id of the parent object
      if value_by_name_proc(join_id).call(object).present?
        {
          name: value_by_name_proc(join_type).call(object), # parent type
          parent: value_by_name_proc(join_id).call(object)  # parent id
        }
      else
        value_by_name_proc(join_type).call(object)
      end
    end
  else
    @value
  end
end

Private Instance Methods

compose_children(value, *parent_objects) click to toggle source
# File lib/chewy/fields/base.rb, line 148
def compose_children(value, *parent_objects)
  return unless value

  children.each_with_object({}) do |field, result|
    result.merge!(field.compose(value, *parent_objects) || {})
  end
end
evaluate(objects) click to toggle source
# File lib/chewy/fields/base.rb, line 95
def evaluate(objects)
  if value.is_a?(Proc)
    value_by_proc(objects, value)
  else
    value_by_name(objects, value)
  end
end
find_allowed_relations(relations) click to toggle source
# File lib/chewy/fields/base.rb, line 141
def find_allowed_relations(relations)
  return [] unless relations
  return relations unless relations.is_a?(Hash)

  (relations.keys + relations.values).flatten.uniq
end
geo_point?() click to toggle source
# File lib/chewy/fields/base.rb, line 83
def geo_point?
  @options[:type].to_s == 'geo_point'
end
ignore_blank?() click to toggle source
# File lib/chewy/fields/base.rb, line 91
def ignore_blank?
  @options.fetch(:ignore_blank) { geo_point? }
end
join_field?() click to toggle source
# File lib/chewy/fields/base.rb, line 87
def join_field?
  @options[:type].to_s == 'join'
end
validate_join_type!(type) click to toggle source
# File lib/chewy/fields/base.rb, line 134
def validate_join_type!(type)
  return unless type
  return if @allowed_relations.include?(type.to_sym)

  raise Chewy::InvalidJoinFieldType.new(type, @name, options[:relations])
end
value_by_name(objects, value) click to toggle source
# File lib/chewy/fields/base.rb, line 114
def value_by_name(objects, value)
  object = objects.first
  message = value.is_a?(Symbol) || value.is_a?(String) ? value.to_sym : name
  value_by_name_proc(message).call(object)
end
value_by_name_proc(message) click to toggle source
# File lib/chewy/fields/base.rb, line 120
def value_by_name_proc(message)
  proc do |object|
    if object.is_a?(Hash)
      if object.key?(message)
        object[message]
      else
        object[message.to_s]
      end
    else
      object.send(message)
    end
  end
end
value_by_proc(objects, value) click to toggle source
# File lib/chewy/fields/base.rb, line 103
def value_by_proc(objects, value)
  object = objects.first
  if value.arity.zero?
    object.instance_exec(&value)
  elsif value.arity.negative?
    value.call(*object)
  else
    value.call(*objects.first(value.arity))
  end
end