web-dev-qa-db-fra.com

Rails: update_attribute vs update_attributes

Object.update_attribute(:only_one_field, "Some Value")
Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")

Ces deux éléments mettront à jour un objet sans avoir à indiquer explicitement à AR de mettre à jour.

L'API Rails dit:

pour update_attribute

Met à jour un seul attribut et enregistre l'enregistrement sans passer par la procédure de validation normale. Ceci est particulièrement utile pour les indicateurs booléens sur des enregistrements existants. La méthode update_attribute régulière dans Base est remplacée par celle-ci lorsque le module de validation est mélangé, ce qui est le cas par défaut.

pour update_attributes

Met à jour tous les attributs du hachage transmis et enregistre l'enregistrement. Si l'objet n'est pas valide, l'enregistrement échouera et false sera renvoyé.

Donc, si je ne veux pas que l'objet soit validé, je dois utiliser update_attribute. Que se passe-t-il si j'ai cette mise à jour sur un before_save, sera-t-il stackoverflow?

Ma question est la suivante: update_attribute ignore-t-il également l'enregistrement avant ou simplement la validation?.

En outre, quelle est la syntaxe correcte pour passer un hachage à update_attributes ... regardez mon exemple en haut.

249
thenengah

Veuillez vous référer à update_attribute . En cliquant sur Afficher la source, vous obtiendrez le code suivant

_      # 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
_

et maintenant se référer update_attributes et regardez son code que vous obtenez

_      # 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 différence entre deux est update_attribute utilise save(false) alors que update_attributes utilise save ou vous peut dire save(true) .

Désolé pour la description longue mais ce que je veux dire est important. save(perform_validation = true) , si _perform_validation_ est faux, il contourne (les sauts seront le mot approprié) tous les validations associés à save.

Pour deuxième question

En outre, quelle est la syntaxe correcte pour passer un hachage à update_attributes ... regardez mon exemple en haut.

Votre exemple est correct.

_Object.update_attributes(:field1 => "value", :field2 => "value2", :field3 => "value3")
_

ou

_Object.update_attributes :field1 => "value", :field2 => "value2", :field3 => "value3"
_

ou si vous obtenez tous les champs data & name dans un hash, dites _params[:user]_ utilisez simplement

_Object.update_attributes(params[:user])
_
321
Salil

Astuce: update_attribute est obsolète dans Rails 4 via Commit a7f4b0a1 . Il supprime update_attribute en faveur de update_column.

75
Matt

update_attribute

Cette méthode met à jour un attribut unique d'objet sans invoquer la validation basée sur un modèle.

obj = Model.find_by_id(params[:id])
obj.update_attribute :language, “Java”

update_attributes

Cette méthode met à jour plusieurs attributs d'un seul objet et passe également la validation basée sur le modèle.

attributes = {:name => “BalaChandar”, :age => 23}
obj = Model.find_by_id(params[:id])
obj.update_attributes(attributes)

J'espère que cette réponse permettra de savoir quand utiliser quelle méthode d'enregistrement actif.

15
Balachandar1887229

A noter également qu'avec update_attribute, l'attribut souhaité à mettre à jour n'a pas besoin d'être mis en liste blanche avec attr_accessible pour le mettre à jour, contrairement à la méthode d'attribution en masse update_attributes qui ne fera que met à jour attr_accessible attributs spécifiés.

12
Kibet Yegon

update_attribute met simplement à jour un seul attribut d'un modèle, mais nous pouvons transmettre plusieurs attributs dans la méthode update_attributes.

Exemple:

user = User.last

#update_attribute
user.update_attribute(:status, "active")

Il passe la validation

#update_attributes
user.update_attributes(first_name: 'update name', status: "active")

il ne met pas à jour si la validation échoue.

7
Shoaib Malik

Grandes réponses. Notez que comme pour Ruby 1.9 et versions ultérieures, vous pouvez (et je pense que vous devriez) utiliser la nouvelle syntaxe de hachage pour update_attributes:

Model.update_attributes(column1: "data", column2: "data")
6
Ziv Galili

Vous pouvez être intéressé par cette publication sur toutes les manières possibles d’attribuer un attribut ou un enregistrement de mise à jour (mis à jour à Rails 4) update_attribute, update, update_column, update_columns etc.http: //www.davidverhasselt. com/set-attributs-in-activerecord / . Par exemple, cela diffère par des aspects tels que l'exécution de validations, le toucher updated_at de l'objet ou le déclenchement de rappels.

En réponse à la question du PO, update_attribute ne transmet pas de rappels.

6
adamliesko

Pour répondre à votre question, update_attribute ignore les "validations" avant la sauvegarde, mais il continue d'exécuter tout autre rappel tel que after_save etc. si vous voulez vraiment "juste mettre à jour la colonne et ignorer n'importe quel AR", alors vous devez utiliser (apparemment)

Model.update_all(...) voir https://stackoverflow.com/a/7243777/3245

4
rogerdpack

update_attribute et update_attributes sont similaires, mais avec une grande différence: update_attribute ne lance pas de validations .

Aussi:

  • update_attribute est utilisé pour mettre à jour l'enregistrement avec l'attribut single.

    Model.update_attribute(:column_name, column_value1)
    
  • update_attributes est utilisé pour mettre à jour l'enregistrement avec multiple attributs.

    Model.update_attributes(:column_name1 => column_value1, :column_name2 => column_value2, ...)
    

Ces deux méthodes sont vraiment faciles à confondre étant donné leurs noms et travaux similaires. Par conséquent, update_attribute est supprimé en faveur de update_column.

Maintenant, dans Rails4 , vous pouvez utiliser Model.update_column(:column_name, column_value) à la place de Model.update_attribute(:column_name, column_value)

Cliquez ici pour obtenir plus d'informations sur update_column.

4
uma

Récemment, j'ai rencontré update_attribute vs. update_attributes et un problème de validation, ainsi des noms similaires, un comportement si différent, si déroutant.

Pour passer hash à update_attribute et contourner la validation, vous pouvez faire:

object = Object.new
object.attributes = {
  field1: 'value',
  field2: 'value2',
  field3: 'value3'
}
object.save!(validate: false)
2

Je pense que votre question est de savoir si avoir un update_attribute dans un before_save entraînera une boucle sans fin (d'appels update_attribute dans des rappels before_save, déclenchés à l'origine par un appel update_attribute)

Je suis presque sûr qu'il ignore le rappel before_save puisqu'il ne sauvegarde pas l'enregistrement. Vous pouvez également enregistrer un enregistrement sans déclencher de validations en utilisant

Model.save false

1
concept47