I'm trying to do something straight forward such as:
User.all(:criteria => {:project_id => 2})
This returns an instance of Mongoid::Criteria
What can I do with this criteria? What if I just want the array of documents returned for further evaluation?
To get an array from a Mongoid::Criteria: use the method .to_a
In Mongoid, the criteria represents the query, not the elements. You can think of a criteria as a filter, a scope, a query object.
Once you have a criteria (scope), you can get the elements, executing an actual query to the database, with a method that is supposed to iterate over the elements or return one element, for example: .first
, .last
, .to_a
, .each
, .map
, etc.
This is more efficient and allows you to compose a complex "query" from other simple ones.
For example, you can create some named scopes in your class:
class User
include Mongoid::Document
field :name, type: String
field :age, type: Integer
field :admin, type: Boolean
scope :admins, where(admin: true) # filter users that are admins
scope :with_name, (name)-> { where(name: name) } # filter users with that name
end
Then you can create some criteria objects:
admins = User.admins
johns = User.with_name('John')
admin_johns = User.admins.with_name('John') # composition of criterias, is like doing ANDs
young = User.where(:age.lt => 25) # the Mongoid method .where also returns a criteria
Up to this point, you didn't fire any query to the mongo database, you were just composing queries.
At any time, you can keep chaining criterias, to refine the query even further:
young_admins = admins.merge(young)
old_admins = admins.where(age.gt => 60)
And finally, get the Array with the elements:
# Execute the query and an array from the criteria
User.all.to_a
User.admins.to_a
admins.to_a
young_admins.to_a
# Execute the query but only return one element
User.first
admins.first
johns.last
# Execute the query and iterate over the returned elements
User.each{|user| ... }
User.admins.each{|admin_user| ... }
johns.map{|john_user| ... }
So, define some named scopes in the Class, then use them to create a criteria, and do the real query when you need it (lazy loading). Criterias handle all of this for you even if you didn't know you needed it.
Criteria
is something like Relation
object in ActiveRecord
You can use it this way
users = User.where(:project_id => 2)
users.each do |user|
puts user.name
end
# or
users.all
This will return []
if there is no any user
users.all.each do |user|
puts user.name
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With