Class: Squeel::Visitors::PredicateVisitor
- Defined in:
- lib/squeel/visitors/predicate_visitor.rb
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
- #arel_predicate_for(attribute, value, parent) ⇒ Object
- #implies_context_change?(v) ⇒ Boolean
- #visit_ActiveRecord_Relation(o, parent) ⇒ Object
- #visit_Array(o, parent) ⇒ Object
- #visit_Hash(o, parent) ⇒ Object
- #visit_Squeel_Nodes_And(o, parent) ⇒ Object
- #visit_Squeel_Nodes_Function(o, parent) ⇒ Object
- #visit_Squeel_Nodes_KeyPath(o, parent) ⇒ Object
- #visit_Squeel_Nodes_Not(o, parent) ⇒ Object
- #visit_Squeel_Nodes_Operation(o, parent) ⇒ Object
- #visit_Squeel_Nodes_Or(o, parent) ⇒ Object
- #visit_Squeel_Nodes_Predicate(o, parent) ⇒ Object
- #visit_Squeel_Nodes_Stub(o, parent) ⇒ Object
- #visit_with_context_change(k, v, parent) ⇒ Object
- #visit_without_context_change(k, v, parent) ⇒ Object
Methods inherited from Base
#accept, #can_accept?, can_accept?, #initialize
Constructor Details
This class inherits a constructor from Squeel::Visitors::Base
Instance Method Details
#arel_predicate_for(attribute, value, parent) ⇒ Object
170 171 172 173 174 175 176 177 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 170 def arel_predicate_for(attribute, value, parent) if [Array, Range, Arel::SelectManager].include?(value.class) attribute.in(value) else value = can_accept?(value) ? accept(value, parent) : value attribute.eq(value) end end |
#implies_context_change?(v) ⇒ Boolean
114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 114 def implies_context_change?(v) case v when Hash, Nodes::Predicate, Nodes::Unary, Nodes::Binary, Nodes::Nary true when Nodes::KeyPath can_accept?(v.endpoint) && !(Nodes::Stub === v.endpoint) when Array (!v.empty? && v.all? {|val| can_accept?(val)}) else false end end |
#visit_ActiveRecord_Relation(o, parent) ⇒ Object
69 70 71 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 69 def visit_ActiveRecord_Relation(o, parent) o.arel end |
#visit_Array(o, parent) ⇒ Object
25 26 27 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 25 def visit_Array(o, parent) o.map { |v| can_accept?(v) ? accept(v, parent) : v }.flatten end |
#visit_Hash(o, parent) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 7 def visit_Hash(o, parent) predicates = o.map do |k, v| if implies_context_change?(v) visit_with_context_change(k, v, parent) else visit_without_context_change(k, v, parent) end end predicates.flatten! if predicates.size > 1 Arel::Nodes::Grouping.new(Arel::Nodes::And.new predicates) else predicates.first end end |
#visit_Squeel_Nodes_And(o, parent) ⇒ Object
102 103 104 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 102 def visit_Squeel_Nodes_And(o, parent) Arel::Nodes::Grouping.new(Arel::Nodes::And.new(accept(o.children, parent))) end |
#visit_Squeel_Nodes_Function(o, parent) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 53 def visit_Squeel_Nodes_Function(o, parent) args = o.args.map do |arg| case arg when Nodes::Function accept(arg, parent) when Nodes::KeyPath can_accept?(arg.endpoint) ? accept(arg, parent) : contextualize(traverse(arg, parent))[arg.endpoint.to_sym] when Symbol, Nodes::Stub Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_sym]) else quoted?(arg) ? Arel.sql(arel_visitor.accept arg) : arg end end Arel::Nodes::NamedFunction.new(o.name, args, o.alias) end |
#visit_Squeel_Nodes_KeyPath(o, parent) ⇒ Object
29 30 31 32 33 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 29 def visit_Squeel_Nodes_KeyPath(o, parent) parent = traverse(o, parent) accept(o.endpoint, parent) end |
#visit_Squeel_Nodes_Not(o, parent) ⇒ Object
110 111 112 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 110 def visit_Squeel_Nodes_Not(o, parent) accept(o.expr, parent).not end |
#visit_Squeel_Nodes_Operation(o, parent) ⇒ Object
73 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 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 73 def visit_Squeel_Nodes_Operation(o, parent) args = o.args.map do |arg| case arg when Nodes::Function accept(arg, parent) when Nodes::KeyPath can_accept?(arg.endpoint) ? accept(arg, parent) : contextualize(traverse(arg, parent))[arg.endpoint.to_sym] when Symbol, Nodes::Stub Arel.sql(arel_visitor.accept contextualize(parent)[arg.to_sym]) else quoted?(arg) ? Arel.sql(arel_visitor.accept arg) : arg end end op = case o.operator when :+ Arel::Nodes::Addition.new(args[0], args[1]) when :- Arel::Nodes::Subtraction.new(args[0], args[1]) when :* Arel::Nodes::Multiplication.new(args[0], args[1]) when :/ Arel::Nodes::Division.new(args[0], args[1]) else Arel::Nodes::InfixOperation(o.operator, args[0], args[1]) end o.alias ? op.as(o.alias) : op end |
#visit_Squeel_Nodes_Or(o, parent) ⇒ Object
106 107 108 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 106 def visit_Squeel_Nodes_Or(o, parent) accept(o.left, parent).or(accept(o.right, parent)) end |
#visit_Squeel_Nodes_Predicate(o, parent) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 39 def visit_Squeel_Nodes_Predicate(o, parent) value = o.value if Nodes::KeyPath === value value = can_accept?(value.endpoint) ? accept(value, parent) : contextualize(traverse(value, parent))[value.endpoint.to_sym] else value = accept(value, parent) if can_accept?(value) end if Nodes::Function === o.expr accept(o.expr, parent).send(o.method_name, value) else contextualize(parent)[o.expr].send(o.method_name, value) end end |
#visit_Squeel_Nodes_Stub(o, parent) ⇒ Object
35 36 37 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 35 def visit_Squeel_Nodes_Stub(o, parent) contextualize(parent)[o.symbol] end |
#visit_with_context_change(k, v, parent) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 127 def visit_with_context_change(k, v, parent) parent = case k when Nodes::KeyPath traverse(k, parent, true) else find(k, parent) end case v when Hash, Nodes::KeyPath, Nodes::Predicate, Nodes::Unary, Nodes::Binary, Nodes::Nary accept(v, parent || k) when Array v.map {|val| accept(val, parent || k)} else raise ArgumentError, <<-END Hashes, Predicates, and arrays of visitables as values imply that their corresponding keys are a parent. This didn't work out so well in the case of key = #{k} and value = #{v}" END end end |
#visit_without_context_change(k, v, parent) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/squeel/visitors/predicate_visitor.rb', line 149 def visit_without_context_change(k, v, parent) case v when Nodes::Stub, Symbol v = contextualize(parent)[v.to_sym] when Nodes::KeyPath # If we could accept the endpoint, we wouldn't be here v = contextualize(traverse(v, parent))[v.endpoint.to_sym] end case k when Nodes::Predicate accept(k % v, parent) when Nodes::Function arel_predicate_for(accept(k, parent), v, parent) when Nodes::KeyPath accept(k % v, parent) else attribute = contextualize(parent)[k.to_sym] arel_predicate_for(attribute, v, parent) end end |