squeel 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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