class Chewy::Search::Parameters

This class is basically a compound storage of the request parameter storages. It encapsulates some storage-collection-handling logic.

@see Chewy::Search::Request#parameters @see Chewy::Search::Parameters::Storage

Constants

QUERY_STRING_STORAGES

Attributes

storages[RW]

@return [{Symbol => Chewy::Search::Parameters::Storage}]

Public Class Methods

new(initial = {}, **kinitial) click to toggle source

Accepts an initial hash as basic values or parameter storages.

@example

Chewy::Search::Parameters.new(limit: 10, offset 10)
Chewy::Search::Parameters.new(
  limit: Chewy::Search::Parameters::Limit.new(10),
  limit: Chewy::Search::Parameters::Offset.new(10)
)

@param initial [{Symbol => Object, Chewy::Search::Parameters::Storage}]

# File lib/chewy/search/parameters.rb, line 39
def initialize(initial = {}, **kinitial)
  @storages = Hash.new do |hash, name|
    hash[name] = self.class.storages[name].new
  end
  initial = initial.deep_dup.merge(kinitial)
  initial.each_with_object(@storages) do |(name, value), result|
    storage_class = self.class.storages[name]
    storage = value.is_a?(storage_class) ? value : storage_class.new(value)
    result[name] = storage
  end
end
storages() click to toggle source

Default storage classes warehouse. It is probably possible to add your own classes here if necessary, but I'm not sure it will work.

@return [{Symbol => Chewy::Search::Parameters::Storage}]

# File lib/chewy/search/parameters.rb, line 19
def self.storages
  @storages ||= Hash.new do |hash, name|
    hash[name] = "Chewy::Search::Parameters::#{name.to_s.camelize}".constantize
  end
end

Public Instance Methods

==(other) click to toggle source

Compares storages by their values.

@param other [Object] any object @return [true, false]

Calls superclass method
# File lib/chewy/search/parameters.rb, line 55
def ==(other)
  super || other.is_a?(self.class) && compare_storages(other)
end
except!(names) click to toggle source

Keeps only specified storages removing everything else.

@param names [Array<String, Symbol>] @return [{Symbol => Chewy::Search::Parameters::Storage}] kept storages hash

# File lib/chewy/search/parameters.rb, line 83
def except!(names)
  @storages.except!(*assert_storages(names))
end
merge!(other) click to toggle source

Takes all the storages and merges them one by one using {Chewy::Search::Parameters::Storage#merge!} method. Merging is implemented in different ways for different storages: for limit, offset and other single-value classes it is a simple value replacement, for boolean storages (explain, none) it uses a disjunction result, for compound values - merging and concatenation, for query, filter, post_filter - it is the “and” operation.

@see Chewy::Search::Parameters::Storage#merge! @return [{Symbol => Chewy::Search::Parameters::Storage}] storages from other parameters

# File lib/chewy/search/parameters.rb, line 98
def merge!(other)
  other.storages.each do |name, storage|
    modify!(name) { merge!(storage) }
  end
end
modify!(name, &block) click to toggle source

Clones the specified storage, performs the operation defined by block on the clone.

@param name [Symbol] parameter name @yield the block is executed in the cloned storage instance binding @return [Chewy::Search::Parameters::Storage]

# File lib/chewy/search/parameters.rb, line 65
def modify!(name, &block)
  @storages[name] = @storages[name].clone.tap do |s|
    s.instance_exec(&block)
  end
end
only!(names) click to toggle source

Removes specified storages from the storages hash.

@param names [Array<String, Symbol>] @return [{Symbol => Chewy::Search::Parameters::Storage}] removed storages hash

# File lib/chewy/search/parameters.rb, line 75
def only!(names)
  @storages.slice!(*assert_storages(names))
end
render() click to toggle source

Renders and merges all the parameter storages into a single hash.

@return [Hash] request body

# File lib/chewy/search/parameters.rb, line 107
def render
  render_query_string_params.merge(render_body)
end

Protected Instance Methods

assert_storages(names) click to toggle source
# File lib/chewy/search/parameters.rb, line 122
def assert_storages(names)
  raise ArgumentError, 'No storage names were specified' if names.empty?

  names = names.map(&:to_sym)
  self.class.storages.values_at(*names)
  names
end
compare_storages(other) click to toggle source
# File lib/chewy/search/parameters.rb, line 117
def compare_storages(other)
  keys = (@storages.keys | other.storages.keys)
  @storages.values_at(*keys) == other.storages.values_at(*keys)
end
initialize_clone(origin) click to toggle source
# File lib/chewy/search/parameters.rb, line 113
def initialize_clone(origin)
  @storages = origin.storages.clone
end
render_body() click to toggle source
# File lib/chewy/search/parameters.rb, line 140
def render_body
  exceptions = %i[filter query none] + QUERY_STRING_STORAGES
  body = @storages.except(*exceptions).values.inject({}) do |result, storage|
    result.merge!(storage.render || {})
  end
  body.merge!(render_query || {})
  {body: body}
end
render_query() click to toggle source
# File lib/chewy/search/parameters.rb, line 149
def render_query
  none = @storages[:none].render

  return none if none

  filter = @storages[:filter].render
  query = @storages[:query].render

  return query unless filter

  if query && query[:query][:bool]
    query[:query][:bool].merge!(filter)
    query
  elsif query
    {query: {bool: {must: query[:query]}.merge!(filter)}}
  else
    {query: {bool: filter}}
  end
end
render_query_string_params() click to toggle source
# File lib/chewy/search/parameters.rb, line 130
def render_query_string_params
  query_string_storages = @storages.select do |storage_name, _|
    QUERY_STRING_STORAGES.include?(storage_name)
  end

  query_string_storages.values.inject({}) do |result, storage|
    result.merge!(storage.render || {})
  end
end