Class: Squeel::Visitors::PredicateVisitor
- Includes:
- PredicateVisitation
- Defined in:
- lib/squeel/visitors/predicate_visitor.rb
Direct Known Subclasses
Constant Summary
Constants included from PredicateVisitation
Squeel::Visitors::PredicateVisitation::EXPAND_BELONGS_TO_METHODS, Squeel::Visitors::PredicateVisitation::FALSE_SQL, Squeel::Visitors::PredicateVisitation::TRUE_SQL
Constants inherited from Visitor
Instance Attribute Summary
Attributes inherited from Visitor
Instance Method Summary collapse
-
#expand_belongs_to(o, parent, association) ⇒ Arel::Nodes::Node
private
Expand a belongs_to association that has an AR::Base value.
-
#implies_hash_context_shift?(v) ⇒ Boolean
private
Whether the given value implies a context change.
-
#visit_Hash(o, parent) ⇒ Array
private
Visit a Hash.
-
#visit_without_hash_context_shift(k, v, parent) ⇒ Object
private
Create a predicate for a given key/value pair.
Methods included from PredicateVisitation
#arel_predicate_for, #attribute_in_array, #attribute_not_in_array, #quote_for_node, #visit_Squeel_Nodes_Predicate, #visit_Squeel_Nodes_Sifter
Methods inherited from Visitor
#accept, #can_visit?, can_visit?, #hash_context_shifted?, #initialize, #quote, #quoted?, #symbolify, #visit, #visit_ActiveRecord_Base, #visit_ActiveRecord_Relation, #visit_Array, #visit_Squeel_Nodes_And, #visit_Squeel_Nodes_As, #visit_Squeel_Nodes_Function, #visit_Squeel_Nodes_Grouping, #visit_Squeel_Nodes_KeyPath, #visit_Squeel_Nodes_Literal, #visit_Squeel_Nodes_Not, #visit_Squeel_Nodes_Operation, #visit_Squeel_Nodes_Or, #visit_Squeel_Nodes_Stub, #visit_Symbol, #visit_passthrough, #visit_with_hash_context_shift
Constructor Details
This class inherits a constructor from Squeel::Visitors::Visitor
Instance Method Details
#expand_belongs_to(o, parent, association) ⇒ Arel::Nodes::Node (private)
Expand a belongs_to association that has an AR::Base value. This allows for queries like:
Post.where(:author => User.first)
Post.where{.eq User.first}
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 20 def (o, parent, association) context = contextualize(parent) ar_base = o.value conditions = [ context[association.foreign_key.to_s].send(o.method_name, ar_base.id) ] if association.[:polymorphic] conditions << [ context[association.foreign_type].send( o.method_name, ar_base.class.base_class.name ) ] end conditions.inject(o.method_name == :not_eq ? :or : :and) end |
#implies_hash_context_shift?(v) ⇒ Boolean (private)
Returns Whether the given value implies a context change.
55 56 57 58 59 60 61 62 63 64 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 55 def implies_hash_context_shift?(v) case v when Hash, Nodes::Predicate, Nodes::Unary, Nodes::Binary, Nodes::Nary, Nodes::Sifter true when Nodes::KeyPath can_visit?(v.endpoint) && !(Nodes::Stub === v.endpoint) else false end end |
#visit_Hash(o, parent) ⇒ Array (private)
Visit a Hash. This entails iterating through each key and value and visiting each value in turn.
42 43 44 45 46 47 48 49 50 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 42 def visit_Hash(o, parent) predicates = super if predicates.size > 1 Arel::Nodes::Grouping.new(Arel::Nodes::And.new predicates) else predicates.first end end |
#visit_without_hash_context_shift(k, v, parent) ⇒ Object (private)
Create a predicate for a given key/value pair. If the value is a Symbol, Stub, or KeyPath, it’s converted to a table.column for the predicate value.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 74 def visit_without_hash_context_shift(k, v, parent) # Short-circuit for stuff like `where(:author => User.first)` # This filthy hack emulates similar behavior in AR PredicateBuilder if ActiveRecord::Base === v && association = classify(parent).reflect_on_association(k.to_sym) return (Nodes::Predicate.new(k, :eq, v), parent, association) end case v when Nodes::Stub, Symbol v = contextualize(parent)[v.to_s] when Nodes::KeyPath # If we could visit the endpoint, we wouldn't be here v = contextualize(traverse(v, parent))[v.endpoint.to_s] end case k when Nodes::Predicate visit(k % quote_for_node(k.expr, v), parent) when Nodes::Function, Nodes::Literal arel_predicate_for(visit(k, parent), quote(v), parent) when Nodes::KeyPath visit(k % quote_for_node(k.endpoint, v), parent) else attr_name = k.to_s attribute = if !hash_context_shifted? && attr_name.include?('.') table_name, attr_name = attr_name.split(/\./, 2) Arel::Table.new(table_name.to_s, :engine => engine)[attr_name.to_s] else contextualize(parent)[attr_name] end arel_predicate_for(attribute, v, parent) end end |