Skip to content

Commit

Permalink
MONGOID-5642 Queryable::Selector#merge! does not properly handle :$in…
Browse files Browse the repository at this point in the history
…/:$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
  • Loading branch information
JohnMaguir authored and comandeo-mongo committed Aug 7, 2023
1 parent 15bf11c commit 65d2d28
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 3 deletions.
2 changes: 1 addition & 1 deletion lib/mongoid/criteria/queryable/selector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def merge!(other)
other.each_pair do |key, value|
if value.is_a?(Hash) && self[key.to_s].is_a?(Hash)
value = self[key.to_s].merge(value) do |_key, old_val, new_val|
case _key
case _key.to_s
when '$in'
new_val & old_val
when '$nin'
Expand Down
77 changes: 75 additions & 2 deletions spec/mongoid/criteria/queryable/selector_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
end
end

context "when selector contains a $nin" do
context "when selector contains a $nin string" do

let(:initial) do
{ "$nin" => ["foo"] }
Expand Down Expand Up @@ -72,7 +72,35 @@
end
end

context "when selector contains a $in" do
context "when selector contains a $nin symbol" do

let(:initial) do
{ :$nin => ["foo"] }
end

before do
selector["field"] = initial
end

context "when merging in a new $nin" do

let(:other) do
{ "field" => { :$nin => ["bar"] } }
end

before do
selector.merge!(other)
end

it "combines the two $nin queries into one" do
expect(selector).to eq({
"field" => { :$nin => ["foo", "bar"] }
})
end
end
end

context "when selector contains a $in string" do

let(:initial) do
{ "$in" => [1, 2] }
Expand Down Expand Up @@ -117,6 +145,51 @@
end
end

context "when selector contains a $in symbol" do

let(:initial) do
{ :$in => [1, 2] }
end

before do
selector["field"] = initial
end

context "when merging in a new $in with an intersecting value" do

let(:other) do
{ "field" => { :$in => [1] } }
end

before do
selector.merge!(other)
end

it "intersects the $in values" do
expect(selector).to eq({
"field" => { :$in => [1] }
})
end
end

context "when merging in a new $in with no intersecting values" do

let(:other) do
{ "field" => { :$in => [3] } }
end

before do
selector.merge!(other)
end

it "intersects the $in values" do
expect(selector).to eq({
"field" => { :$in => [] }
})
end
end
end

context "when selector is not nested" do

before do
Expand Down

0 comments on commit 65d2d28

Please sign in to comment.