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_Hash!(o, parent) ⇒ Object private
-
#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, #accept!, can_visit?, #can_visit?, #hash_context_shifted?, #initialize, #quote, #quoted?, #symbolify, #visit, #visit!, #visit_ActiveRecord_Base, #visit_ActiveRecord_Relation, #visit_Arel_Nodes_Node, #visit_Array, #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_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, #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.
65 66 67 68 69 70 71 72 73 74 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 65 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_Hash!(o, parent) ⇒ Object (private)
52 53 54 55 56 57 58 59 60 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 52 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.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 84 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 |