Hello, I just tried updating from 7.0.5 to 7.1.0 and the problem is after reading the latest Mongoid doc about the new way selectors works, I'm still haven't found a way to rewrite my first broken selector, here is how it looks:
I have a has_many relation, through which I want to do a OR between two clauses, I used to do it with model.relation.any_of({}, {}), but since 7.1.0 the $or clauses includes the relation criteria too (model_id) which is clearly not what I want.
Here is a running example:
require 'mongoid' Mongoid.configure do |config| config.clients.default = { hosts: ['localhost:27017'], database: 'test', } end Mongo::Logger.logger.level = :warn class User include Mongoid::Document has_many :comments end class Comment include Mongoid::Document belongs_to :user, optional: true field :time, type: Integer end user = User.first || User.create! Comment.delete_all user.comments.create! time: 2 user.comments.create! time: 4 user.comments.create! time: 8 # ← should return user.comments.create! time: nil # ← should return Comment.create! time: nil Comment.create! time: 8 p Mongoid::VERSION puts "expect 2, got #{user.comments.any_of({:time.gt => 5}, {:time => nil}).count}, criteria:" p user.comments.any_of({:time.gt => 5}, {:time => nil}).selector # Mongoid 7.0.5 (ok) # expect 2, got 2, criteria: # {"user_id"=>BSON::ObjectId('5e740088b2c79a527394bf4d'), "$or"=>[{"time"=>{"$gt"=>5}}, {"time"=>nil}]} # Mongoid 7.1.0 (not what I wanted) # expect 2, got 6, criteria: # {"$or"=>[{"user_id"=>BSON::ObjectId('5e740088b2c79a527394bf4d')}, {"time"=>{"$gt"=>5}}, {"time"=>nil}]} # Also tried: puts "expect 2, got #{user.comments.gt(time: 5).or(time: nil).count}, criteria:" p user.comments.gt(time: 5).or(time: nil).selector # Mongoid 7.0.5 (not what I wanted) # expect 2, got 0, criteria: # {"user_id"=>BSON::ObjectId('5e740088b2c79a527394bf4d'), "time"=>{"$gt"=>5}, "$or"=>[{"time"=>nil}]} # Mongoid 7.1.0 (not what I wanted) # expect 2, got 3, criteria: # {"$or"=>[{"user_id"=>BSON::ObjectId('5e740088b2c79a527394bf4d'), "time"=>{"$gt"=>5}}, {"time"=>nil}]}
How am I supposed to write this query now? I saw in the doc "When a logical operator is used, it operates on the criteria built up to that point and its argument" but the thing is it's a relation here I can't just put the or before the relation.
See MONGOID-4697 for the implementation of these changes and MONGOID-4855 for discussions about "any_of" vs "or".
- duplicates
-
MONGOID-4852 Make the upgrading/changelog section of Mongoid documentation useful
- Closed
- is related to
-
MONGOID-4861 Useless $and when calling Foo.and(Foo.or(...))
- Closed
-
MONGOID-4862 Make any_of behave like or but not disjunct the receiver
- Closed