From 903128c312169dff9fac3649a00c19a4f6b2c70e Mon Sep 17 00:00:00 2001 From: DarshanaVenkatesh <70602567+DarshanaVenkatesh@users.noreply.github.com> Date: Fri, 13 Dec 2024 09:57:55 -0800 Subject: [PATCH] MONGOID-5780 Fix chaining nots resulting in incorrect negation state (backport to 9.0) --- lib/mongoid/criteria/queryable/selectable.rb | 2 +- .../criteria/queryable/selectable_spec.rb | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/mongoid/criteria/queryable/selectable.rb b/lib/mongoid/criteria/queryable/selectable.rb index 3a4373baa4..2d308a09bd 100644 --- a/lib/mongoid/criteria/queryable/selectable.rb +++ b/lib/mongoid/criteria/queryable/selectable.rb @@ -553,7 +553,7 @@ def negating? # @return [ Selectable ] The new selectable. def not(*criteria) if criteria.empty? - dup.tap { |query| query.negating = true } + dup.tap { |query| query.negating = !query.negating } else criteria.compact.inject(self.clone) do |c, new_s| if new_s.is_a?(Selectable) diff --git a/spec/mongoid/criteria/queryable/selectable_spec.rb b/spec/mongoid/criteria/queryable/selectable_spec.rb index 59159f925f..9cc4b2443a 100644 --- a/spec/mongoid/criteria/queryable/selectable_spec.rb +++ b/spec/mongoid/criteria/queryable/selectable_spec.rb @@ -1939,6 +1939,35 @@ def localized? end end + describe "#not" do + context "when negating a criterion" do + let(:selection) do + query.not(field: /value/) + end + + it "adds the $not selector" do + expect(selection.selector).to eq({ + "field" => { "$not" => /value/ } + }) + end + + it "returns a cloned query" do + expect(selection).to_not equal(query) + end + + context "when toggling negation state" do + it "negates the negating value" do + expect(query.negating).to be_nil + negated_query = query.not + expect(negated_query.negating).to be true + double_negated_query = negated_query.not + expect(double_negated_query.negating).to be false + end + end + end + end + + describe Symbol do describe "#all" do