diff --git a/lib/mongoid/criteria/queryable/storable.rb b/lib/mongoid/criteria/queryable/storable.rb index 6cca86d45f..95ebd7ab53 100644 --- a/lib/mongoid/criteria/queryable/storable.rb +++ b/lib/mongoid/criteria/queryable/storable.rb @@ -47,7 +47,7 @@ def add_field_expression(field, value) if value.is_a?(Hash) && selector[field].is_a?(Hash) && value.keys.all? { |key| key_s = key.to_s - key_s.start_with?('$') && !selector[field].key?(key_s) + key_s.start_with?('$') && !selector[field].keys.map(&:to_s).include?(key_s) } then # Multiple operators can be combined on the same field by diff --git a/spec/mongoid/criteria/queryable/storable_spec.rb b/spec/mongoid/criteria/queryable/storable_spec.rb index ec9351f250..65052d90a1 100644 --- a/spec/mongoid/criteria/queryable/storable_spec.rb +++ b/spec/mongoid/criteria/queryable/storable_spec.rb @@ -210,7 +210,79 @@ } end end + + context 'when value is a hash combine values with different operator keys' do + let(:base) do + query.add_field_expression('foo', {'$in' => ['bar']}) + end + + let(:modified) do + base.add_field_expression('foo', {'$nin' => ['zoom']}) + end + + it 'combines the conditions using $and' do + modified.selector.should == { + 'foo' => { + '$in' => ['bar'], + '$nin' => ['zoom'] + } + } + end + end + + context 'when value is a hash with symbol operator key combine values with different operator keys' do + let(:base) do + query.add_field_expression('foo', {:$in => ['bar']}) + end + + let(:modified) do + base.add_field_expression('foo', {:$nin => ['zoom']}) + end + + it 'combines the conditions using $and' do + modified.selector.should == { + 'foo' => { + :$in => ['bar'], + :$nin => ['zoom'] + } + } + end + end + + context 'when value is a hash add values with same operator keys using $and' do + let(:base) do + query.add_field_expression('foo', {'$in' => ['bar']}) + end + + let(:modified) do + base.add_field_expression('foo', {'$in' => ['zoom']}) + end + + it 'adds the new condition using $and' do + modified.selector.should == { + 'foo' => {'$in' => ['bar']}, + '$and' => ['foo' => {'$in' => ['zoom']}] + } + end + end + + context 'when value is a hash with symbol operator key add values with same operator keys using $and' do + let(:base) do + query.add_field_expression('foo', {:$in => ['bar']}) + end + + let(:modified) do + base.add_field_expression('foo', {:$in => ['zoom']}) + end + + it 'adds the new condition using $and' do + modified.selector.should == { + 'foo' => {:$in => ['bar']}, + '$and' => ['foo' => {:$in => ['zoom']}] + } + end end +end describe '#add_operator_expression' do let(:query_method) { :add_operator_expression }