ruby-on-rails - callbacks - update attributes in model rails
Rails: update_attribute vs update_attributes (11)
Creo que su pregunta es si tener un atributo update_attribute en un before_save conducirá a un bucle sin fin (de las llamadas update_attribute en las devoluciones de llamada before_save, originadas originalmente por una llamada update_attribute)
Estoy bastante seguro de que no pasa por alto la devolución de llamada before_save ya que en realidad no guarda el registro. También puede guardar un registro sin activar las validaciones usando
Modelo.save falso
Object.update_attribute(:only_one_field, "Some Value")
Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")
Ambos actualizarán un objeto sin tener que decirle explícitamente a AR que actualice.
Rails API dice:
para update_attribute
Actualiza un solo atributo y guarda el registro sin pasar por el procedimiento de validación normal. Esto es especialmente útil para las banderas booleanas en los registros existentes. El método regular update_attribute en Base se reemplaza con esto cuando se mezcla el módulo de validaciones, que es por defecto.
para update_attributes
Actualiza todos los atributos del hash pasado y guarda el registro. Si el objeto no es válido, el guardado fallará y se devolverá falso.
Entonces, si no quiero que el objeto sea validado, debería usar update_attribute. ¿Qué pasa si tengo esta actualización en un before_save, será stackoverflow?
Mi pregunta es ¿update_attribute también pasa por alto antes de guardar o solo la validación.
Además, ¿cuál es la sintaxis correcta para pasar un hash a update_attributes ... mira mi ejemplo en la parte superior?
Es posible que le interese visitar esta publicación de blog sobre todas las formas posibles de asignar un atributo o un registro de actualización (actualizado a Rails 4) update_attribute, update, update_column, update_columns etc.
http://www.davidverhasselt.com/set-attributes-in-activerecord/ . Por ejemplo, difiere en aspectos como ejecutar validaciones, tocar updated_at del objeto o activar devoluciones de llamada.
Como respuesta a la pregunta del OP, update_attribute
no pasa las devoluciones de llamada.
Grandes respuestas. Observe que en cuanto a Ruby 1.9 y superior, podría (y creo que debería) usar la nueva sintaxis de hash para update_attributes:
Model.update_attributes(column1: "data", column2: "data")
Para responder a su pregunta, update_attribute omite las "validaciones" previas al guardado, pero aún se ejecuta cualquier otra devolución de llamada como after_save
etc. Entonces, si realmente desea "simplemente actualizar la columna y omitir cualquier crucero AR", entonces debe usar (aparentemente)
Model.update_all(...)
vea https://.com/a/7243777/32453
Por favor, consulte update_attribute
. Al hacer clic en Mostrar fuente obtendrá el siguiente código
# File vendor/rails/activerecord/lib/active_record/base.rb, line 2614
2614: def update_attribute(name, value)
2615: send(name.to_s + ''='', value)
2616: save(false)
2617: end
y ahora consulte update_attributes
y mire el código que obtiene.
# File vendor/rails/activerecord/lib/active_record/base.rb, line 2621
2621: def update_attributes(attributes)
2622: self.attributes = attributes
2623: save
2624: end
la diferencia entre dos es que update_attribute
usa save(false)
mientras que update_attributes
usa save(false) o puedes decir save(false) .
Lo siento por la descripción larga pero lo que quiero decir es importante. save(perform_validation = true)
, si perform_validation
es false, omite (skips será la palabra adecuada) todas las validaciones asociadas con save
.
Para la segunda pregunta
Además, ¿cuál es la sintaxis correcta para pasar un hash a update_attributes ... mira mi ejemplo en la parte superior?
Tu ejemplo es correcto.
Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")
o
Object.update_attributes :field1 => "value", :field2 => "value2", :field3 => "value3"
o si obtiene todos los campos datos y nombre en un hash, diga params[:user]
aquí use solo
Object.update_attributes(params[:user])
Recientemente me encontré con update_attribute
vs. update_attributes
y problema de validación, por lo que nombres similares, comportamiento tan diferente, tan confuso.
Para pasar el hash a update_attribute
y evitar la validación, puede hacer:
object = Object.new
object.attributes = {
field1: ''value'',
field2: ''value2'',
field3: ''value3''
}
object.save!(validate: false)
También es de destacar que con update_attribute
, el atributo que se desea actualizar no necesita ser incluido en la lista blanca con attr_accessible
para actualizarlo en oposición al método de asignación en masa update_attributes
que solo actualizará attr_accessible
los atributos especificados.
update_attribute
simplemente actualiza solo un atributo de un modelo, pero podemos pasar múltiples atributos en el método update_attributes
.
Ejemplo:
user = User.last
#update_attribute
user.update_attribute(:status, "active")
Pasa la validación.
#update_attributes
user.update_attributes(first_name: ''update name'', status: "active")
no se actualiza si falla la validación.
update_attribute
y update_attributes
son similares, pero con una gran diferencia: update_attribute
no ejecuta validaciones.
También:
update_attribute
se usa para actualizar el registro con un solo atributo.Model.update_attribute(:column_name, column_value1)
update_attributes
se usa para actualizar el registro con múltiples atributos.Model.update_attributes(:column_name1 => column_value1, :column_name2 => column_value2, ...)
Estos dos métodos son realmente fáciles de confundir dados sus nombres y trabajos similares. Por lo tanto, update_attribute
se está eliminando en favor de update_column
.
Ahora, en Rails4 puedes usar Model.update_column(:column_name, column_value)
en el lugar de Model.update_attribute(:column_name, column_value)
Haga clic aquí para obtener más información sobre update_column
.
Consejo: update_attribute
está en desuso en Rails 4 a través de Commit a7f4b0a1 . Elimina update_attribute
a favor de update_column
.
atributo_actualizacion
Este método actualiza el atributo único del objeto sin invocar la validación basada en modelos.
obj = Model.find_by_id(params[:id])
obj.update_attribute :language, “java”
update_attributes
Este método actualiza varios atributos de un solo objeto y también pasa la validación basada en el modelo.
attributes = {:name => “BalaChandar”, :age => 23}
obj = Model.find_by_id(params[:id])
obj.update_attributes(attributes)
Espero que esta respuesta se aclare cuándo usar qué método de registro activo.