Skip to content

Commit 8af6ba9

Browse files
JohnMaguircomandeo-mongo
authored andcommitted
MONGOID-5642 Queryable::Selector#merge! does not properly handle :$in/:$nin keys (#5655)
* Change Mongoid::Criteria::Queryable::Selector#merge! to correctly merge $in and $nin when provided as a symbol as well as a string * Mongoid::Criteria::Queryable::Selector#merge! convert to strings before matching * cleanup whitespace
1 parent b4e050c commit 8af6ba9

File tree

2 files changed

+76
-3
lines changed

2 files changed

+76
-3
lines changed

lib/mongoid/criteria/queryable/selector.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def merge!(other)
2020
other.each_pair do |key, value|
2121
if value.is_a?(Hash) && self[key.to_s].is_a?(Hash)
2222
value = self[key.to_s].merge(value) do |_key, old_val, new_val|
23-
case _key
23+
case _key.to_s
2424
when '$in'
2525
new_val & old_val
2626
when '$nin'

spec/mongoid/criteria/queryable/selector_spec.rb

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
end
4545
end
4646

47-
context "when selector contains a $nin" do
47+
context "when selector contains a $nin string" do
4848

4949
let(:initial) do
5050
{ "$nin" => ["foo"] }
@@ -72,7 +72,35 @@
7272
end
7373
end
7474

75-
context "when selector contains a $in" do
75+
context "when selector contains a $nin symbol" do
76+
77+
let(:initial) do
78+
{ :$nin => ["foo"] }
79+
end
80+
81+
before do
82+
selector["field"] = initial
83+
end
84+
85+
context "when merging in a new $nin" do
86+
87+
let(:other) do
88+
{ "field" => { :$nin => ["bar"] } }
89+
end
90+
91+
before do
92+
selector.merge!(other)
93+
end
94+
95+
it "combines the two $nin queries into one" do
96+
expect(selector).to eq({
97+
"field" => { :$nin => ["foo", "bar"] }
98+
})
99+
end
100+
end
101+
end
102+
103+
context "when selector contains a $in string" do
76104

77105
let(:initial) do
78106
{ "$in" => [1, 2] }
@@ -117,6 +145,51 @@
117145
end
118146
end
119147

148+
context "when selector contains a $in symbol" do
149+
150+
let(:initial) do
151+
{ :$in => [1, 2] }
152+
end
153+
154+
before do
155+
selector["field"] = initial
156+
end
157+
158+
context "when merging in a new $in with an intersecting value" do
159+
160+
let(:other) do
161+
{ "field" => { :$in => [1] } }
162+
end
163+
164+
before do
165+
selector.merge!(other)
166+
end
167+
168+
it "intersects the $in values" do
169+
expect(selector).to eq({
170+
"field" => { :$in => [1] }
171+
})
172+
end
173+
end
174+
175+
context "when merging in a new $in with no intersecting values" do
176+
177+
let(:other) do
178+
{ "field" => { :$in => [3] } }
179+
end
180+
181+
before do
182+
selector.merge!(other)
183+
end
184+
185+
it "intersects the $in values" do
186+
expect(selector).to eq({
187+
"field" => { :$in => [] }
188+
})
189+
end
190+
end
191+
end
192+
120193
context "when selector is not nested" do
121194

122195
before do

0 commit comments

Comments
 (0)