В Mongoid критерии представляют запрос, а не элементы.
Вы можете рассматривать критерии как фильтр, область действия, объект запроса.
Если у вас есть критерий (область действия), вы можете получить элементы, выполняя фактический запрос к базе данных, с помощью метода, который должен выполнять итерации по элементам или возвращать один элемент, например: .first
, .last
, .to_a
, .each
, .map
и т. Д.
Это более эффективно и позволяет вам составлять сложные "запросы" из других простых.
Например, вы можете создать несколько именованных областей в вашем классе:
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
Затем вы можете создать несколько критериальных объектов:
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
До этого момента, вы не запускали ни одного запроса к базе данных mongo, вы просто составляли запросы.
В любое время вы можете сохранить критерии цепочки, чтобы еще больше уточнить запрос:
young_admins = admins.merge(young)
old_admins = admins.where(age.gt => 60)
И, наконец, получите Массив с элементами:
# 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| ... }
Итак, определите некоторые именованные области в классе, затем используйте их для создания критериев и выполняйте реальный запрос, когда вам это нужно (ленивая загрузка). Критерии обрабатывают все это для вас, даже если вы не знали, что вам это нужно.