Pour affecter en masse des valeurs à un modèle ActiveRecord sans enregistrer, utilisez les méthodes assign_attributes
ou attributes=
. 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:
@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }
@user.attributes = { model: "Sierra", year: "2012", looks: "Sexy" }
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 de assign_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:
@user.attributes = [ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ]
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:
@user.assign_attributes([ { model: "Sierra" }, { year: "2012" }, { looks: "Sexy" } ])
assign_attributes
déclenchera une NoMethodError
exception pour stringify_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 et assign_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 toujoursassign_attributes
au lieu de attributes=
.
Rails 4
Dans Rails 4, attributes=
est simplement un alias pour assign_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éthodes valid?
et invalid?
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:
@user.assign_attributes{ model: "Sierra", year: "2012", looks: "Sexy" }.valid?
Cela vous donnera la possibilité de gérer tous les problèmes de validation avant d'appeler save
.