2011-01-16 8 views
6

Estoy usando Rails y mongoid para trabajar con mongodb.Actualización booleana simple de datos con mongdb?

Normalmente en rieles cuando se trabaja con Active: Record, tiene acceso al método .toggle! que simplemente le permite invertir el valor de un campo booleano en su db.

Desafortunadamente, este método no está disponible para MongoDB:

user = User.first 
user.toggle!(:admin) 
NoMethodError: undefined method `toggle!' for #<User:0x00000100eee700> 

Esto es lamentable ... y estúpidamente lo suficientemente no veo cómo moverse sin algún código complicado ...

Cualquier sugerencia sobre cómo lograr el mismo resultado de manera concisa?

Gracias,

Alex

PS: también uno de los problemas es que cuando quiero modificar el campo, pasa por la validación de nuevo ... y que está pidiendo el: contraseña cual Don 't guardar en el PP, por lo que:

User.first.admin = !User.first.admin 

no va a trabajar incluso :(

Respuesta

6

la cuestión aquí es específicamente MongoId, no mongodb toggle! es una parte de 0., pero afortunadamente no es difícil de replicar.

def toggle!(field) 
    send "#{field}=", !self.send("#{field}?") 
    save :validation => false 
end 

Añadir que en su modelo (o añadirlo en un módulo, e incluirlo en su modelo), y sus modelos MongoId obtendrán una funcionalidad equivalente a lo que estamos acostumbrados en AR. Leerá el valor del campo, lo invertirá, lo escribirá (a través del colocador, según la documentación toggle!) y luego guardará el documento, sin pasar por la validación.

+0

Este es realmente impresionante! Exactamente lo que estaba buscando ... :) ¿No sabía esa sintaxis con el envío? No estoy seguro de qué es exactamente? – Alex

+0

'send' invoca un método para (" envía un mensaje a ") un objeto. '@ foo.bar (: baz)' es lo mismo que '@ foo.send (" bar ",: baz)' - ya que especifica el nombre del método con send, puede pasar variables y cosas por el estilo. Esto se usa mucho en la metaprogramación de Ruby. –

+0

Gracias por la explicación. Sin embargo, después de realizar pruebas exhaustivas, en realidad no elude toda la validación. Tengo una validates_length_of: password,: minimum => 6,: maximum => 40, y al usar la barra pasará a través de mí un error en la longitud de la contraseña ... :(Pero no en las presencias validadas, etc. Y se saltea el attr_accesible, etc. por lo que es casi perfecto además de la validación de longitud – Alex

0

Ok la validación no funciona debido a un tipo, el código debe ser:

save :validate => false (not :validation) 
0
# Get object's boolean field and toggle it 
# @param [Object] mongoid object 
# @param [String, Symbol] flag 
# @example 
# foo = User.find('123') 
# toggle_flag!(object: foo, flag: :bar) 

def toggle_flag!(object:, flag:) 
    object.update(flag => !object[flag]) 
    object.save! 
end 
+0

¡Explique su código! –

+0

¡He terminado! Usé YARD para explicarlo. – arkhwise

Cuestiones relacionadas