File tree Expand file tree Collapse file tree 3 files changed +71
-2
lines changed
lib/active_record/relation Expand file tree Collapse file tree 3 files changed +71
-2
lines changed Original file line number Diff line number Diff line change
1
+ * Fix ` #merge ` with ` #or ` or ` #and ` and a mixture of attributes and SQL strings resulting in an incorrect query.
2
+
3
+ ``` ruby
4
+ base = Comment .joins(:post ).where(user_id: 1 ).where(" recent = 1" )
5
+ puts base.merge(base.where(draft: true ).or(Post .where(archived: true ))).to_sql
6
+ ```
7
+
8
+ Before:
9
+
10
+ ` ` ` SQL
11
+ SELECT "comments".* FROM "comments"
12
+ INNER JOIN "posts" ON "posts"."id" = "comments"."post_id"
13
+ WHERE (recent = 1)
14
+ AND (
15
+ "comments"."user_id" = 1
16
+ AND (recent = 1)
17
+ AND "comments"."draft" = 1
18
+ OR "posts"."archived" = 1
19
+ )
20
+ ` ` `
21
+
22
+ After:
23
+
24
+ ` ` ` SQL
25
+ SELECT "comments".* FROM "comments"
26
+ INNER JOIN "posts" ON "posts"."id" = "comments"."post_id"
27
+ WHERE "comments"."user_id" = 1
28
+ AND (recent = 1)
29
+ AND (
30
+ "comments"."user_id" = 1
31
+ AND (recent = 1)
32
+ AND "comments"."draft" = 1
33
+ OR "posts"."archived" = 1
34
+ )
35
+ ` ` `
36
+
37
+ * Joshua Young *
38
+
1
39
* Make schema dumper to account for ` ActiveRecord.dump_schemas` when dumping in ` :ruby` format .
2
40
3
41
* fatkodima*
Original file line number Diff line number Diff line change @@ -135,10 +135,14 @@ def each_attributes
135
135
136
136
def extract_attribute ( node )
137
137
attr_node = nil
138
- Arel . fetch_attribute ( node ) do |attr |
139
- return if attr_node &.!= attr # all attr nodes should be the same
138
+
139
+ valid_attrs = Arel . fetch_attribute ( node ) do |attr |
140
+ !attr_node || attr_node == attr # all attr nodes should be the same
141
+ ensure
140
142
attr_node = attr
141
143
end
144
+ return unless valid_attrs # all nested nodes should yield an attribute
145
+
142
146
attr_node
143
147
end
144
148
Original file line number Diff line number Diff line change @@ -74,6 +74,33 @@ class WhereClauseTest < ActiveRecord::TestCase
74
74
assert_equal expected , a . merge ( b )
75
75
end
76
76
77
+ test "merge with or/and correctly handles SQL literals and attributes" do
78
+ a = WhereClause . new ( [
79
+ table [ "id" ] . eq ( 1 ) ,
80
+ Arel ::Nodes ::Grouping . new ( Arel . sql ( "foo = bar" ) )
81
+ ] )
82
+ b = ( a + WhereClause . new ( [ table [ "attr_1" ] . eq ( "val_1" ) ] ) ) . or (
83
+ WhereClause . new ( [ table [ "attr_2" ] . eq ( "val_2" ) ] )
84
+ )
85
+
86
+ expected = WhereClause . new ( [
87
+ table [ "id" ] . eq ( 1 ) ,
88
+ Arel ::Nodes ::Grouping . new ( Arel . sql ( "foo = bar" ) ) ,
89
+ Arel ::Nodes ::Grouping . new (
90
+ Arel ::Nodes ::Or . new ( [
91
+ Arel ::Nodes ::And . new ( [
92
+ table [ "id" ] . eq ( 1 ) ,
93
+ Arel ::Nodes ::Grouping . new ( Arel . sql ( "foo = bar" ) ) ,
94
+ table [ "attr_1" ] . eq ( "val_1" )
95
+ ] ) ,
96
+ table [ "attr_2" ] . eq ( "val_2" )
97
+ ] )
98
+ )
99
+ ] )
100
+
101
+ assert_equal expected , a . merge ( b )
102
+ end
103
+
77
104
test "a clause knows if it is empty" do
78
105
assert_empty WhereClause . empty
79
106
assert_not_empty WhereClause . new ( [ Arel . sql ( "anything" ) ] )
You can’t perform that action at this time.
0 commit comments