Class: Clearly::Query::Composer

Inherits:
Object
  • Object
show all
Includes:
Clearly::Query::Compose::Conditions, Validate
Defined in:
lib/clearly/query/composer.rb

Overview

Class that composes a query from a filter hash.

Constant Summary collapse

OPERATOR_ALL_TEXT =

All text fields operator.

:all_text_fields

Constants included from Clearly::Query::Compose::Conditions

Clearly::Query::Compose::Conditions::OPERATORS, Clearly::Query::Compose::Conditions::OPERATORS_COMPARISON, Clearly::Query::Compose::Conditions::OPERATORS_LOGICAL, Clearly::Query::Compose::Conditions::OPERATORS_RANGE, Clearly::Query::Compose::Conditions::OPERATORS_REGEX, Clearly::Query::Compose::Conditions::OPERATORS_SPECIAL, Clearly::Query::Compose::Conditions::OPERATORS_SUBSET

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Validate

#like_syntax, #sanitize_like_value, #sanitize_similar_to_value, #validate_array, #validate_array_items, #validate_association, #validate_boolean, #validate_condition, #validate_definition, #validate_definition_instance, #validate_float, #validate_hash, #validate_integer, #validate_model, #validate_name, #validate_node_or_attribute, #validate_not_blank, #validate_query, #validate_spec_association, #validate_symbol, #validate_table, #validate_table_column

Methods included from Clearly::Query::Compose::Conditions

#condition_combine, #condition_combine_new, #condition_components, #condition_node, #condition_node_comparison, #condition_node_subset

Methods included from Clearly::Query::Compose::Range

#parse_interval, #parse_range

Constructor Details

#initialize(definitions) ⇒ Clearly::Query::Composer

Create an instance of Composer using a set of model query spec definitions.

Parameters:


18
19
20
21
22
23
24
25
26
# File 'lib/clearly/query/composer.rb', line 18

def initialize(definitions)
  validate_not_blank(definitions)
  validate_array(definitions)
  validate_definition_instance(definitions[0])
  validate_array_items(definitions)
  @definitions = definitions
  @table_names = definitions.map { |d| d.table.name }
  self
end

Instance Attribute Details

#definitionsArray<Clearly::Query::Definition> (readonly)

Returns available definitions

Returns:


13
14
15
# File 'lib/clearly/query/composer.rb', line 13

def definitions
  @definitions
end

Class Method Details

.from_active_recordClearly::Query::Composer

Create an instance of Composer from all ActiveRecord models.


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/clearly/query/composer.rb', line 30

def self.from_active_record
  models = ActiveRecord::Base
               .descendants
               .reject { |d| d.name == 'ActiveRecord::SchemaMigration' }
               .sort { |a, b| a.name <=> b.name }
               .uniq { |d| d.arel_table.name }

  definitions = models.map do |d|
    if d.name.include?('::InternalMetadata')
      # ignore the AR metadata
    elsif d.name.include?('HABTM_')
      Clearly::Query::Definition.new({table: d.arel_table})
    else
      Clearly::Query::Definition.new({model: d, hash: d.clearly_query_def})
    end
  end

  Composer.new(definitions.compact)
end

Instance Method Details

#conditions(model, hash) ⇒ Array<Arel::Nodes::Node>

Composes Arel conditions from a parsed filter hash.

Parameters:

  • model (ActiveRecord::Base)
  • hash (Hash)

Returns:

  • (Array<Arel::Nodes::Node>)

69
70
71
72
73
74
75
76
77
78
# File 'lib/clearly/query/composer.rb', line 69

def conditions(model, hash)
  validate_model(model)
  validate_hash(hash)

  definition = select_definition_from_model(model)
  cleaned_query_hash = Clearly::Query::Cleaner.new.do(hash)

  # default combiner is :and
  parse_conditions(definition, :and, cleaned_query_hash)
end

#query(model, hash) ⇒ ActiveRecord::Relation

Composes a query from a parsed filter hash.

Parameters:

  • model (ActiveRecord::Base)
  • hash (Hash)

Returns:

  • (ActiveRecord::Relation)

54
55
56
57
58
59
60
61
62
63
# File 'lib/clearly/query/composer.rb', line 54

def query(model, hash)
  conditions = conditions(model, hash)
  query = model.all
  validate_query(query)
  conditions.each do |condition|
    validate_condition(condition)
    query = query.where(condition)
  end
  query
end