Existe-t-il une alternative à update_attributes qui ne sauvegarde pas l'enregistrement?
Je pourrais donc faire quelque chose comme:
@car = Car.new(:make => 'GMC')
#other processing
@car.update_attributes(:model => 'Sierra', :year => "2012", :looks => "Super Sexy, wanna make love to it")
#other processing
@car.save
BTW, je sais que je peux @car.model = 'Sierra'
, mais je veux les mettre à jour tous sur une seule ligne.
assign_attributes
apidock.com/rails/ActiveRecord/Base/assign_attributesRéponses:
Je crois que ce que vous recherchez est
assign_attributes
.C'est fondamentalement la même chose que update_attributes mais cela ne sauvegarde pas l'enregistrement:
la source
attr_accessible :is_admin, :as => :admin
:;)attr_protected :is_admin
. Ou:attr_accessible :name
Le point étant que dans cet exemple,: is_admin est protégé. Je dois également noter que tenter d'attribuer en masse un attribut protégé avec.assign_attributes
soulève effectivement unActiveModel::MassAssignmentSecurity::Error
, même si cela n'est pas illustré dans l'exemple.user.assign_attributes({ :name => 'Josh', :is_admin => true })
déclenche un message d'erreur et ne définit pas réellement la propriété de nom de l'utilisateur.Vous pouvez utiliser
assign_attributes
ouattributes=
(ce sont les mêmes)Mise à jour des méthodes de triche (pour Rails 6):
update
=assign_attributes
+save
attributes=
= alias deassign_attributes
update_attributes
= obsolète, alias deupdate
Source:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/persistence.rb
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_assignment .rb
Une autre feuille de triche:
http://www.davidverhasselt.com/set-attributes-in-activerecord/#cheat-sheet
la source
Vous pouvez utiliser la méthode des «attributs»:
Source: http://api.rubyonrails.org/classes/ActiveRecord/Base.html
attributes = (new_attributes, guard_protected_attributes = true) Vous permet de définir tous les attributs à la fois en passant un hachage avec des clés correspondant aux noms d'attributs (qui correspondent à nouveau aux noms de colonne).
Si guard_protected_attributes a la valeur true (valeur par défaut), les attributs sensibles peuvent être protégés de cette forme d'affectation en masse à l'aide de la macro attr_protected. Ou vous pouvez également spécifier les attributs accessibles avec la macro attr_accessible. Ensuite, tous les attributs non inclus ne seront pas autorisés à être affectés en masse.
la source
Pour affecter en masse des valeurs à un modèle ActiveRecord sans enregistrer, utilisez les méthodes
assign_attributes
ouattributes=
. Ces méthodes sont disponibles dans Rails 3 et versions ultérieures. Cependant, il y a des différences mineures et des problèmes liés à la version à connaître.Les deux méthodes suivent cette utilisation:
Notez qu'aucune des méthodes n'effectuera de validations ou exécutera de rappels; les rappels et la validation auront lieu lors de l'
save
appel.Rails 3
attributes=
diffère légèrement deassign_attributes
dans Rails 3.attributes=
vérifiera que l'argument qui lui est passé est un Hash, et retourne immédiatement s'il ne l'est pas;assign_attributes
n'a pas un tel contrôle Hash. Consultez la documentation de l'API d'attribution d'attributs ActiveRecord pourattributes=
.Le code non valide suivant échouera silencieusement en retournant simplement sans définir les attributs:
attributes=
se comportera silencieusement comme si les affectations avaient été effectuées avec succès, alors qu'en réalité, elles ne l'ont pas été.Ce code non valide
assign_attributes
lèvera une exception lors d'une tentative de stringification des clés de hachage du tableau englobant:assign_attributes
déclenchera uneNoMethodError
exception pourstringify_keys
, indiquant que le premier argument n'est pas un hachage. L'exception elle-même n'est pas très informative sur la cause réelle, mais le fait qu'une exception se produit est très important.La seule différence entre ces cas est la méthode utilisée pour l'affectation en masse:
attributes=
réussit en silence etassign_attributes
déclenche une exception pour informer qu'une erreur s'est produite.Ces exemples peuvent sembler artificiels, et ils le sont dans une certaine mesure, mais ce type d'erreur peut facilement se produire lors de la conversion de données à partir d'une API, ou même simplement en utilisant une série de transformation de données et en oubliant
Hash[]
les résultats de la finale.map
. Conservez quelques lignes de code 50 ci-dessus et 3 fonctions supprimées de votre attribution d'attribut, et vous avez une recette pour l'échec.La leçon avec Rails 3 est la suivante: utilisez toujours
assign_attributes
au lieu deattributes=
.Rails 4
Dans Rails 4,
attributes=
est simplement un alias pourassign_attributes
. Consultez la documentation de l'API d'attribution d'attributs ActiveRecord pourattributes=
.Avec Rails 4, les deux méthodes peuvent être utilisées de manière interchangeable. Le fait de ne pas passer un hachage comme premier argument entraînera une exception très utile:
ArgumentError: When assigning attributes, you must pass a hash as an argument.
Validations
Si vous pré-volez des affectations en préparation à un
save
, vous pourriez également être intéressé par la validation avant l'enregistrement. Vous pouvez utiliser les méthodesvalid?
etinvalid?
pour cela. Les deux renvoient des valeurs booléennes.valid?
renvoie true si le modèle non enregistré passe toutes les validations ou false dans le cas contraire.invalid?
est tout simplement l'inverse devalid?
valid?
peut être utilisé comme ceci:Cela vous donnera la possibilité de gérer tous les problèmes de validation avant d'appeler
save
.la source