2011-09-28 9 views
7

que estoy tratando de hacer algo sencillo como:¿Cómo funcionan los "criterios" de Mongoid?

User.all(:criteria => {:project_id => 2}) 

Esto devuelve una instancia de Mongoid::Criteria

¿Qué puedo hacer con este criterio? ¿Qué sucede si solo quiero que se devuelva la matriz de documentos para una evaluación posterior?

+0

Así que 'all' en ActiveRecord devuelve una matriz. Desea llamar a 'execute' para obtener la matriz. 'User.where (project_id: 2) .execute' – Travis

Respuesta

2

Criteria es algo así como Relation objeto en ActiveRecord

Se puede utilizar esta forma

users = User.where(:project_id => 2) 
users.each do |user| 
    puts user.name 
end 
# or 
users.all 

Esto devolverá [] si no hay ningún usuario

users.all.each do |user| 
    puts user.name 
end 
+0

Si no hay usuarios que coincidan con ese criterio, cuando ejecute puts user.name, obtengo el' 'Criteria'' en sí. ¿Hay alguna manera de evitar eso? – randombits

+1

si ahora hay usuarios 'puts user.name' no se ejecutará nunca – fl00r

+1

' users.all' no devuelve una matriz. Devuelve otro criterio y generalmente no es necesario. Para obtener una matriz a partir de los criterios, use .to_a – tothemario

15

En Mongoid, la criterios representa la consulta, no los elementos. Puede pensar en un criterio como un filtro, un alcance, un objeto de consulta.

Una vez que tenga un criterio (alcance), puede obtener los elementos, ejecutando una consulta real en la base de datos, con un método que se supone que itera sobre los elementos o devuelve un elemento, por ejemplo: .first, .last, .to_a, .each, .map, etc.

Esto es más eficiente y le permite componer una "consulta" compleja de otras simples.

Por ejemplo, puede crear algunos ámbitos por nombre en su clase:

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 

continuación, puede crear algunos criterios de objetos:

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 

Hasta este punto, que no disparó cualquier consulta a la base de datos de mongo, solo estaba componiendo consultas.

En cualquier momento, puede mantener el encadenamiento de criterios, para refinar la consulta aún más:

young_admins = admins.merge(young) 
old_admins = admins.where(age.gt => 60) 

Y, por último, obtener la matriz con los elementos:

# 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| ... } 

Por lo tanto, definir algunos nombrado ámbitos en la clase, luego utilícelos para crear un criterio, y haga la consulta real cuando la necesite (carga diferida). Los criterios manejan todo esto por usted incluso si no sabía que lo necesitaba.

1

Para obtener una matriz de un Mongoid :: Criterios: use el método .to_a

Cuestiones relacionadas