squeel 1.0.9 → 1.0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/CHANGELOG.md +10 -0
  2. data/lib/squeel.rb +5 -0
  3. data/lib/squeel/adapters/active_record/3.0/association_preload_extensions.rb +2 -2
  4. data/lib/squeel/adapters/active_record/3.0/relation_extensions.rb +98 -46
  5. data/lib/squeel/adapters/active_record/3.1/preloader_extensions.rb +2 -2
  6. data/lib/squeel/adapters/active_record/3.1/relation_extensions.rb +71 -85
  7. data/lib/squeel/adapters/active_record/base_extensions.rb +0 -19
  8. data/lib/squeel/adapters/active_record/relation_extensions.rb +6 -9
  9. data/lib/squeel/nodes/binary.rb +4 -0
  10. data/lib/squeel/nodes/function.rb +10 -0
  11. data/lib/squeel/nodes/nary.rb +1 -1
  12. data/lib/squeel/nodes/order.rb +11 -1
  13. data/lib/squeel/nodes/predicate.rb +2 -2
  14. data/lib/squeel/nodes/stub.rb +2 -0
  15. data/lib/squeel/nodes/unary.rb +4 -0
  16. data/lib/squeel/version.rb +1 -1
  17. data/lib/squeel/visitors.rb +10 -3
  18. data/lib/squeel/visitors/from_visitor.rb +6 -0
  19. data/lib/squeel/visitors/group_visitor.rb +6 -0
  20. data/lib/squeel/visitors/having_visitor.rb +9 -0
  21. data/lib/squeel/visitors/order_visitor.rb +20 -0
  22. data/lib/squeel/visitors/predicate_visitation.rb +126 -0
  23. data/lib/squeel/visitors/predicate_visitor.rb +3 -326
  24. data/lib/squeel/visitors/{symbol_visitor.rb → preload_visitor.rb} +4 -4
  25. data/lib/squeel/visitors/select_visitor.rb +7 -0
  26. data/lib/squeel/visitors/visitor.rb +244 -12
  27. data/lib/squeel/visitors/where_visitor.rb +8 -0
  28. data/spec/helpers/squeel_helper.rb +14 -1
  29. data/spec/squeel/adapters/active_record/relation_extensions_spec.rb +65 -49
  30. data/spec/squeel/nodes/as_spec.rb +20 -0
  31. data/spec/squeel/nodes/function_spec.rb +6 -0
  32. data/spec/squeel/nodes/grouping_spec.rb +6 -0
  33. data/spec/squeel/nodes/key_path_spec.rb +3 -3
  34. data/spec/squeel/nodes/operation_spec.rb +6 -0
  35. data/spec/squeel/nodes/order_spec.rb +6 -1
  36. data/spec/squeel/nodes/predicate_operators_spec.rb +1 -1
  37. data/spec/squeel/nodes/predicate_spec.rb +14 -1
  38. data/spec/squeel/nodes/sifter_spec.rb +2 -1
  39. data/spec/squeel/nodes/stub_spec.rb +4 -0
  40. data/spec/squeel/visitors/order_visitor_spec.rb +36 -0
  41. data/spec/squeel/visitors/{symbol_visitor_spec.rb → preload_visitor_spec.rb} +4 -3
  42. data/spec/squeel/visitors/select_visitor_spec.rb +26 -0
  43. data/spec/squeel/visitors/{attribute_visitor_spec.rb → visitor_spec.rb} +23 -37
  44. data/spec/support/models.rb +4 -0
  45. metadata +22 -10
  46. data/lib/squeel/visitors/attribute_visitor.rb +0 -214
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 1.0.11 (2012-09-03)
2
+
3
+ * Fixed issue #157, resolving problems when joining the same table twice.
4
+ * Allow predicates in order/select values
5
+ * Support Relation#from in Squeel DSL
6
+
7
+ ## 1.0.10 (2012-09-01)
8
+
9
+ * Yanked from RubyGems.org due to semantic versioning oversight
10
+
1
11
  ## 1.0.9 (2012-08-06)
2
12
 
3
13
  * Fix issue with duplication of order conditions in default_scope on AR 3.0.x
data/lib/squeel.rb CHANGED
@@ -13,6 +13,11 @@ module Squeel
13
13
  $VERBOSE = original_verbosity
14
14
  end
15
15
 
16
+ def self.deprecate(message)
17
+ external_caller = caller.find {|s| !s.include?('/lib/squeel/')}
18
+ warn "DEPRECATION WARNING: #{message} (called from #{external_caller})"
19
+ end
20
+
16
21
  # Set up initial predicate aliases
17
22
  Constants::PREDICATE_ALIASES.each do |original, aliases|
18
23
  aliases.each do |aliaz|
@@ -4,10 +4,10 @@ module Squeel
4
4
  module AssociationPreloadExtensions
5
5
 
6
6
  def preload_associations(records, associations, preload_options={})
7
- super(records, Visitors::SymbolVisitor.new.accept(associations), preload_options)
7
+ super(records, Visitors::PreloadVisitor.new.accept(associations), preload_options)
8
8
  end
9
9
 
10
10
  end
11
11
  end
12
12
  end
13
- end
13
+ end
@@ -13,37 +13,37 @@ module Squeel
13
13
 
14
14
  # Returns a JoinDependency for the current relation.
15
15
  #
16
- # We don't need to clear out @join_dependency by overriding #reset, because
17
- # the default #reset already does this, despite never setting it anywhere that
18
- # I can find. Serendipity, I say!
16
+ # We don't need to clear out @join_dependency by overriding #reset,
17
+ # because the default #reset already does this, despite never setting
18
+ # it anywhere that I can find. Serendipity, I say!
19
19
  def join_dependency
20
20
  @join_dependency ||= (build_join_dependency(table, @joins_values) && @join_dependency)
21
21
  end
22
22
 
23
- def predicate_visitor
24
- Visitors::PredicateVisitor.new(
25
- Context.new(join_dependency)
26
- )
27
- end
28
-
29
- def attribute_visitor
30
- Visitors::AttributeVisitor.new(
31
- Context.new(join_dependency)
32
- )
23
+ %w(where having group order select from).each do |visitor|
24
+ define_method "#{visitor}_visit" do |values|
25
+ Visitors.const_get("#{visitor.capitalize}Visitor").new(
26
+ Context.new(join_dependency)
27
+ ).accept(values)
28
+ end
33
29
  end
34
30
 
35
31
  # We need to be able to support merging two relations without having
36
- # to get our hooks too deeply into ActiveRecord. AR's relation
37
- # merge functionality is very cool, but relatively complex, to
38
- # handle the various edge cases. Our best shot at avoiding strange
39
- # behavior with Squeel loaded is to visit the *_values arrays in
40
- # the relations we're merging, and then use the default AR merge
41
- # code on the result.
42
- def merge(r, skip_visit = false)
43
- if skip_visit or not ::ActiveRecord::Relation === r
44
- super(r)
32
+ # to get our hooks too deeply into ActiveRecord. That proves to be
33
+ # easier said than done. I hate Relation#merge. If Squeel has a
34
+ # nemesis, Relation#merge would be it.
35
+ #
36
+ # Whatever code you see here currently is my current best attempt at
37
+ # coexisting peacefully with said nemesis.
38
+ def merge(r, equalities_resolved = false)
39
+ if ::ActiveRecord::Relation === r && !equalities_resolved
40
+ if self.table_name != r.table_name
41
+ super(r.visited)
42
+ else
43
+ merge_resolving_duplicate_squeel_equalities(r)
44
+ end
45
45
  else
46
- visited.merge(r.visited, true)
46
+ super(r)
47
47
  end
48
48
  end
49
49
 
@@ -52,15 +52,12 @@ module Squeel
52
52
  end
53
53
 
54
54
  def visit!
55
- predicate_viz = predicate_visitor
56
- attribute_viz = attribute_visitor
57
-
58
- @where_values = predicate_viz.accept((@where_values - ['']).uniq)
59
- @having_values = predicate_viz.accept(@having_values.uniq.reject{|h| h.blank?})
55
+ @where_values = where_visit((@where_values - ['']).uniq)
56
+ @having_values = having_visit(@having_values.uniq.reject{|h| h.blank?})
60
57
  # FIXME: AR barfs on ARel attributes in group_values. Workaround?
61
- # @group_values = attribute_viz.accept(@group_values.uniq.reject{|g| g.blank?})
62
- @order_values = attribute_viz.accept(@order_values.uniq.reject{|o| o.blank?})
63
- @select_values = attribute_viz.accept(@select_values.uniq)
58
+ # @group_values = group_visit(@group_values.uniq.reject{|g| g.blank?})
59
+ @order_values = order_visit(@order_values.uniq.reject{|o| o.blank?})
60
+ @select_values = select_visit(@select_values.uniq)
64
61
 
65
62
  self
66
63
  end
@@ -70,23 +67,20 @@ module Squeel
70
67
 
71
68
  arel = build_join_dependency(arel, @joins_values) unless @joins_values.empty?
72
69
 
73
- predicate_viz = predicate_visitor
74
- attribute_viz = attribute_visitor
75
-
76
- arel = collapse_wheres(arel, predicate_viz.accept((@where_values - ['']).uniq))
70
+ arel = collapse_wheres(arel, where_visit((@where_values - ['']).uniq))
77
71
 
78
- arel = arel.having(*predicate_viz.accept(@having_values.uniq.reject{|h| h.blank?})) unless @having_values.empty?
72
+ arel = arel.having(*having_visit(@having_values.uniq.reject{|h| h.blank?})) unless @having_values.empty?
79
73
 
80
74
  arel = arel.take(connection.sanitize_limit(@limit_value)) if @limit_value
81
75
  arel = arel.skip(@offset_value) if @offset_value
82
76
 
83
- arel = arel.group(*attribute_viz.accept(@group_values.uniq.reject{|g| g.blank?})) unless @group_values.empty?
77
+ arel = arel.group(*group_visit(@group_values.uniq.reject{|g| g.blank?})) unless @group_values.empty?
84
78
 
85
- arel = arel.order(*attribute_viz.accept(@order_values.uniq.reject{|o| o.blank?})) unless @order_values.empty?
79
+ arel = arel.order(*order_visit(@order_values.uniq.reject{|o| o.blank?})) unless @order_values.empty?
86
80
 
87
- arel = build_select(arel, attribute_viz.accept(@select_values.uniq))
81
+ arel = build_select(arel, select_visit(@select_values.uniq))
88
82
 
89
- arel = arel.from(@from_value) if @from_value
83
+ arel = arel.from(from_visit(@from_value)) if @from_value
90
84
  arel = arel.lock(@lock_value) if @lock_value
91
85
 
92
86
  arel
@@ -104,7 +98,7 @@ module Squeel
104
98
  # Rails core, but for now, I'm going to settle for this hack
105
99
  # that tries really hard to coerce things to a string.
106
100
  def select_for_count
107
- visited_values = attribute_visitor.accept(select_values.uniq)
101
+ visited_values = select_visit(select_values.uniq)
108
102
  if visited_values.size == 1
109
103
  select = visited_values.first
110
104
 
@@ -245,6 +239,14 @@ module Squeel
245
239
  end
246
240
  end
247
241
 
242
+ def from(*args)
243
+ if block_given? && args.empty?
244
+ super(DSL.eval &Proc.new)
245
+ else
246
+ super
247
+ end
248
+ end
249
+
248
250
  def build_where(opts, other = [])
249
251
  case opts
250
252
  when String, Array
@@ -285,7 +287,10 @@ module Squeel
285
287
  nodes.map { |node|
286
288
  case node
287
289
  when Arel::Nodes::Equality
288
- node if node.left.relation.name == table_name
290
+ if node.left.respond_to?(:relation) &&
291
+ node.left.relation.name == table_name
292
+ node
293
+ end
289
294
  when Arel::Nodes::Grouping
290
295
  find_equality_predicates([node.expr])
291
296
  when Arel::Nodes::And
@@ -296,6 +301,48 @@ module Squeel
296
301
  }.compact.flatten
297
302
  end
298
303
 
304
+ def flatten_nodes(nodes)
305
+ nodes.map { |node|
306
+ case node
307
+ when Array
308
+ flatten_nodes(node)
309
+ when Nodes::And
310
+ flatten_nodes(node.children)
311
+ when Nodes::Grouping
312
+ flatten_nodes(node.expr)
313
+ else
314
+ node
315
+ end
316
+ }.flatten
317
+ end
318
+
319
+ def merge_resolving_duplicate_squeel_equalities(r)
320
+ left = clone
321
+ right = r.clone
322
+ left.where_values = flatten_nodes(left.where_values)
323
+ right.where_values = flatten_nodes(right.where_values)
324
+ right_equalities = right.where_values.select do |obj|
325
+ Nodes::Predicate === obj && obj.method_name == :eq
326
+ end
327
+ right.where_values -= right_equalities
328
+ left.where_values = resolve_duplicate_squeel_equalities(
329
+ left.where_values + right_equalities
330
+ )
331
+ left.merge(right, true)
332
+ end
333
+
334
+ def resolve_duplicate_squeel_equalities(wheres)
335
+ seen = {}
336
+ wheres.reverse.reject { |n|
337
+ nuke = false
338
+ if Nodes::Predicate === n && n.method_name == :eq
339
+ nuke = seen[n.expr]
340
+ seen[n.expr] = true
341
+ end
342
+ nuke
343
+ }.reverse
344
+ end
345
+
299
346
  # Simulate the logic that occurs in #to_a
300
347
  #
301
348
  # This will let us get a dump of the SQL that will be run against the
@@ -316,10 +363,12 @@ module Squeel
316
363
  # ...
317
364
  # Since you're still looking, let me explain this horrible
318
365
  # transgression you see before you.
366
+ #
319
367
  # You see, Relation#where_values_hash is defined on the
320
- # ActiveRecord::Relation class. Since it's defined there, but
321
- # I would very much like to modify its behavior, I have three
322
- # choices.
368
+ # ActiveRecord::Relation class, itself.
369
+ #
370
+ # Since it's defined there, but I would very much like to modify its
371
+ # behavior, I have three choices:
323
372
  #
324
373
  # 1. Inherit from ActiveRecord::Relation in a Squeel::Relation
325
374
  # class, and make an attempt to usurp all of the various calls
@@ -335,6 +384,9 @@ module Squeel
335
384
  #
336
385
  # I opted to go with #3. Except for the hail Hansson thing.
337
386
  # Unless you're DHH, in which case, I totally said them.
387
+ #
388
+ # If you'd like to read more about alias_method_chain, see
389
+ # http://erniemiller.org/2011/02/03/when-to-use-alias_method_chain/
338
390
 
339
391
  def self.included(base)
340
392
  base.class_eval do
@@ -343,7 +395,7 @@ module Squeel
343
395
  end
344
396
 
345
397
  def where_values_hash_with_squeel
346
- equalities = find_equality_predicates(predicate_visitor.accept(@where_values))
398
+ equalities = find_equality_predicates(where_visit(@where_values))
347
399
 
348
400
  Hash[equalities.map { |where| [where.left.name, where.right] }]
349
401
  end
@@ -11,11 +11,11 @@ module Squeel
11
11
 
12
12
  def run_with_squeel
13
13
  unless records.empty?
14
- Visitors::SymbolVisitor.new.accept(associations).each { |association| preload(association) }
14
+ Visitors::PreloadVisitor.new.accept(associations).each { |association| preload(association) }
15
15
  end
16
16
  end
17
17
 
18
18
  end
19
19
  end
20
20
  end
21
- end
21
+ end
@@ -13,37 +13,37 @@ module Squeel
13
13
 
14
14
  # Returns a JoinDependency for the current relation.
15
15
  #
16
- # We don't need to clear out @join_dependency by overriding #reset, because
17
- # the default #reset already does this, despite never setting it anywhere that
18
- # I can find. Serendipity, I say!
16
+ # We don't need to clear out @join_dependency by overriding #reset,
17
+ # because the default #reset already does this, despite never setting
18
+ # it anywhere that I can find. Serendipity, I say!
19
19
  def join_dependency
20
20
  @join_dependency ||= (build_join_dependency(table.from(table), @joins_values) && @join_dependency)
21
21
  end
22
22
 
23
- def predicate_visitor
24
- Visitors::PredicateVisitor.new(
25
- Context.new(join_dependency)
26
- )
27
- end
28
-
29
- def attribute_visitor
30
- Visitors::AttributeVisitor.new(
31
- Context.new(join_dependency)
32
- )
23
+ %w(where having group order select from).each do |visitor|
24
+ define_method "#{visitor}_visit" do |values|
25
+ Visitors.const_get("#{visitor.capitalize}Visitor").new(
26
+ Context.new(join_dependency)
27
+ ).accept(values)
28
+ end
33
29
  end
34
30
 
35
31
  # We need to be able to support merging two relations without having
36
- # to get our hooks too deeply into ActiveRecord. AR's relation
37
- # merge functionality is very cool, but relatively complex, to
38
- # handle the various edge cases. Our best shot at avoiding strange
39
- # behavior with Squeel loaded is to visit the *_values arrays in
40
- # the relations we're merging, and then use the default AR merge
41
- # code on the result.
42
- def merge(r, skip_visit = false)
43
- if skip_visit or not ::ActiveRecord::Relation === r
44
- super(r)
32
+ # to get our hooks too deeply into ActiveRecord. That proves to be
33
+ # easier said than done. I hate Relation#merge. If Squeel has a
34
+ # nemesis, Relation#merge would be it.
35
+ #
36
+ # Whatever code you see here currently is my current best attempt at
37
+ # coexisting peacefully with said nemesis.
38
+ def merge(r, equalities_resolved = false)
39
+ if ::ActiveRecord::Relation === r && !equalities_resolved
40
+ if self.table_name != r.table_name
41
+ super(r.visited)
42
+ else
43
+ merge_resolving_duplicate_squeel_equalities(r)
44
+ end
45
45
  else
46
- visited.merge(r.visited, true)
46
+ super(r)
47
47
  end
48
48
  end
49
49
 
@@ -52,15 +52,12 @@ module Squeel
52
52
  end
53
53
 
54
54
  def visit!
55
- predicate_viz = predicate_visitor
56
- attribute_viz = attribute_visitor
57
-
58
- @where_values = predicate_viz.accept((@where_values - ['']).uniq)
59
- @having_values = predicate_viz.accept(@having_values.uniq.reject{|h| h.blank?})
55
+ @where_values = where_visit((@where_values - ['']).uniq)
56
+ @having_values = having_visit(@having_values.uniq.reject{|h| h.blank?})
60
57
  # FIXME: AR barfs on ARel attributes in group_values. Workaround?
61
- # @group_values = attribute_viz.accept(@group_values.uniq.reject{|g| g.blank?})
62
- @order_values = attribute_viz.accept(@order_values.uniq.reject{|o| o.blank?})
63
- @select_values = attribute_viz.accept(@select_values.uniq)
58
+ # @group_values = group_visit(@group_values.uniq.reject{|g| g.blank?})
59
+ @order_values = order_visit(@order_values.uniq.reject{|o| o.blank?})
60
+ @select_values = select_visit(@select_values.uniq)
64
61
 
65
62
  self
66
63
  end
@@ -70,26 +67,23 @@ module Squeel
70
67
 
71
68
  build_join_dependency(arel, @joins_values) unless @joins_values.empty?
72
69
 
73
- predicate_viz = predicate_visitor
74
- attribute_viz = attribute_visitor
75
-
76
- collapse_wheres(arel, predicate_viz.accept((@where_values - ['']).uniq))
70
+ collapse_wheres(arel, where_visit((@where_values - ['']).uniq))
77
71
 
78
- arel.having(*predicate_viz.accept(@having_values.uniq.reject{|h| h.blank?})) unless @having_values.empty?
72
+ arel.having(*having_visit(@having_values.uniq.reject{|h| h.blank?})) unless @having_values.empty?
79
73
 
80
74
  arel.take(connection.sanitize_limit(@limit_value)) if @limit_value
81
75
  arel.skip(@offset_value) if @offset_value
82
76
 
83
- arel.group(*attribute_viz.accept(@group_values.uniq.reject{|g| g.blank?})) unless @group_values.empty?
77
+ arel.group(*group_visit(@group_values.uniq.reject{|g| g.blank?})) unless @group_values.empty?
84
78
 
85
79
  order = @reorder_value ? @reorder_value : @order_values
86
- order = attribute_viz.accept(order)
80
+ order = order_visit(order)
87
81
  order = reverse_sql_order(attrs_to_orderings(order)) if @reverse_order_value
88
82
  arel.order(*order.uniq.reject{|o| o.blank?}) unless order.empty?
89
83
 
90
- build_select(arel, attribute_viz.accept(@select_values.uniq))
84
+ build_select(arel, select_visit(@select_values.uniq))
91
85
 
92
- arel.from(@from_value) if @from_value
86
+ arel.from(from_visit(@from_value)) if @from_value
93
87
  arel.lock(@lock_value) if @lock_value
94
88
 
95
89
  arel
@@ -115,7 +109,7 @@ module Squeel
115
109
  # Rails core, but for now, I'm going to settle for this hack
116
110
  # that tries really hard to coerce things to a string.
117
111
  def select_for_count
118
- visited_values = attribute_visitor.accept(select_values.uniq)
112
+ visited_values = select_visit(select_values.uniq)
119
113
  if visited_values.size == 1
120
114
  select = visited_values.first
121
115
 
@@ -263,6 +257,14 @@ module Squeel
263
257
  end
264
258
  end
265
259
 
260
+ def from(*args)
261
+ if block_given? && args.empty?
262
+ super(DSL.eval &Proc.new)
263
+ else
264
+ super
265
+ end
266
+ end
267
+
266
268
  def build_where(opts, other = [])
267
269
  case opts
268
270
  when String, Array
@@ -301,7 +303,10 @@ module Squeel
301
303
  nodes.map { |node|
302
304
  case node
303
305
  when Arel::Nodes::Equality
304
- node if node.left.relation.name == table_name
306
+ if node.left.respond_to?(:relation) &&
307
+ node.left.relation.name == table_name
308
+ node
309
+ end
305
310
  when Arel::Nodes::Grouping
306
311
  find_equality_predicates([node.expr])
307
312
  when Arel::Nodes::And
@@ -327,9 +332,24 @@ module Squeel
327
332
  }.flatten
328
333
  end
329
334
 
330
- def overwrite_squeel_equalities(wheres)
335
+ def merge_resolving_duplicate_squeel_equalities(r)
336
+ left = clone
337
+ right = r.clone
338
+ left.where_values = flatten_nodes(left.where_values)
339
+ right.where_values = flatten_nodes(right.where_values)
340
+ right_equalities = right.where_values.select do |obj|
341
+ Nodes::Predicate === obj && obj.method_name == :eq
342
+ end
343
+ right.where_values -= right_equalities
344
+ left.where_values = resolve_duplicate_squeel_equalities(
345
+ left.where_values + right_equalities
346
+ )
347
+ left.merge(right, true)
348
+ end
349
+
350
+ def resolve_duplicate_squeel_equalities(wheres)
331
351
  seen = {}
332
- flatten_nodes(wheres).reverse.reject { |n|
352
+ wheres.reverse.reject { |n|
333
353
  nuke = false
334
354
  if Nodes::Predicate === n && n.method_name == :eq
335
355
  nuke = seen[n.expr]
@@ -360,11 +380,11 @@ module Squeel
360
380
  # Since you're still looking, let me explain this horrible
361
381
  # transgression you see before you.
362
382
  #
363
- # You see, Relation#where_values_hash and with_default_scope
364
- # are defined on the ActiveRecord::Relation class, itself.
365
- # ActiveRecord::Relation class. Since they're defined there, but
366
- # I would very much like to modify their behavior, I have three
367
- # choices.
383
+ # You see, Relation#where_values_hash is defined on the
384
+ # ActiveRecord::Relation class, itself.
385
+ #
386
+ # Since it's defined there, but I would very much like to modify its
387
+ # behavior, I have three choices:
368
388
  #
369
389
  # 1. Inherit from ActiveRecord::Relation in a Squeel::Relation
370
390
  # class, and make an attempt to usurp all of the various calls
@@ -372,7 +392,7 @@ module Squeel
372
392
  # evil stuff with constant reassignment, all for the sake of
373
393
  # being able to use super().
374
394
  #
375
- # 2. Submit a patch to Rails core, breaking these methods off into
395
+ # 2. Submit a patch to Rails core, breaking this method off into
376
396
  # another module, all for my own selfish desire to use super()
377
397
  # while mucking about in Rails internals.
378
398
  #
@@ -387,7 +407,6 @@ module Squeel
387
407
  def self.included(base)
388
408
  base.class_eval do
389
409
  alias_method_chain :where_values_hash, :squeel
390
- alias_method_chain :with_default_scope, :squeel
391
410
  end
392
411
  end
393
412
 
@@ -397,44 +416,11 @@ module Squeel
397
416
  # And and Grouping nodes, which are equivalent to seeing top-level
398
417
  # Equality nodes in stock AR terms.
399
418
  def where_values_hash_with_squeel
400
- equalities = find_equality_predicates(predicate_visitor.accept(with_default_scope.where_values))
419
+ equalities = find_equality_predicates(where_visit(with_default_scope.where_values))
401
420
 
402
421
  Hash[equalities.map { |where| [where.left.name, where.right] }]
403
422
  end
404
423
 
405
- # with_default_scope was added to ActiveRecord ~> 3.1 in order to
406
- # address https://github.com/rails/rails/issues/1233. Unfortunately,
407
- # it plays havoc with Squeel's approach of visiting both sides of
408
- # a relation merge. Thankfully, when merging with a relation from
409
- # the same AR::Base, it's unnecessary to visit...
410
- #
411
- # Except, of course, this means we have to handle the edge case
412
- # where equalities are duplicated on both sides of the merge, in
413
- # which case, unlike all other chained relation calls, the latter
414
- # equality overwrites the former.
415
- #
416
- # The workaround using overwrite_squeel_equalities works as long
417
- # as you stick to the Squeel DSL, but breaks down if you throw hash
418
- # conditions into the mix. If anyone's got any suggestions, I'm all
419
- # ears. Otherwise, just stick to the Squeel DSL.
420
- #
421
- # Or, don't use default scopes. They're the devil, anyway. I can't
422
- # remember the last time I used one and didn't find myself
423
- # regretting the decision later.
424
- def with_default_scope_with_squeel
425
- if default_scoped? &&
426
- default_scope = klass.build_default_scope_with_squeel
427
- default_scope = default_scope.merge(self, true)
428
- default_scope.default_scoped = false
429
- default_scope.where_values = overwrite_squeel_equalities(
430
- default_scope.where_values + self.where_values
431
- )
432
- default_scope
433
- else
434
- self
435
- end
436
- end
437
-
438
424
  end
439
425
  end
440
426
  end