enregistrer un actif dossiers de tableau
J'ai un tableau comme ceci
a = []
a << B.new(:name => "c")
a << B.new(:name => "s")
a << B.new(:name => "e")
a << B.new(:name => "t")
Comment je peux l'enregistrer à la fois?
OriginalL'auteur Luca Romagnoli | 2010-02-18
Vous devez vous connecter pour publier un commentaire.
Cela appel
B#save
sur chaque élément d'un tableau.Jamais appel
save
, vérifier la valeur de retour (vrai oder false) ou de l'utilisation.save!
de laisser rails déclencher une exception lorsque quelque chose n'est pas correct!OriginalL'auteur Jordan Running
Cela va créer une transaction qui effectue une boucle sur chaque élément du tableau et les appels de l'élément.enregistrer sur elle.
Vous pouvez lire sur ActiveRecord Transactions et chaque méthode dans les Rails et Ruby Api.
save!
. Il semble que la transaction est seulement interrompue si il y a une exception.Aïe. Vous avez raison. J'ai mis à jour la réponse.
Maintenant, vous devez attraper
ActiveRecord::RecordInvalid
quelque part.OriginalL'auteur Benjamin Manns
Donc je pense que nous avons besoin d'un milieu de terrain à Alexeï soulève des exceptions et l'abandon de la transaction et de la Jordanie one-liner solution. Puis-je proposer:
Cela vous donnera un peu des deux mondes: une opération de reprise, dont la connaissance enregistrements ont échoué et vous donne même accès à la validation des erreurs y figurent.
!b.errors.blank?
, pourquoi ne pasb.errors.present?
pourrait également être
a.reject{|b| b.errors.blank?}
. Principalement parce qu'il était presque 3 ans et c'était un hors-la-brassard réponse. Aussi parce que Ruby, ai-je le droit?OriginalL'auteur kayakyakr
Je sais que c'est une vieille question, mais je suis surpris personne n'a pensé à ceci:
oui, mais il court-circuit en outre enregistre donc vous aurez seulement savoir à propos de la première qui a échoué, pas sur tous. Cela peut faire un monde de différence quand vous avez par exemple 30 objets enregistrés dans la rangée, la moitié d'entre eux ont échoué et vous devez montrer la validation de l'utilisateur, d'une manière qui ne sera pas lui faire re-envoyer le formulaire à 15 fois pour corriger les 15 erreurs l'un après l'autre juste à apprendre encore une autre chose est cassé 😉
OriginalL'auteur d4rky
Emballage
save
dans la transaction ne sera pas suffisant: si la validation n'est pas passé, il n'y aura pas d'exception soulevée et aucune restauration déclenchée.Je peux vous proposer ceci:
Juste faire
B.transaction do a.each(&:save!) end
n'est pas une option, parce que la transaction de bloc ne sauvera pas toute exception autre queActiveRecord::Rollback
, et l'application se bloquer sur l'échec de la validation.Je ne sais pas comment le vérifier par la suite si les dossiers ont été enregistrés.
Mise à jour. Comme quelqu'un l'a downrated ma réponse, je suppose que la personne a été la recherche d'un couper-coller de la solution :), voici donc quelques (moche :)) la manière de traiter l'échec/réussite de la valeur:
save!
est parfait, letransaction do
bloc reviennent automatiquement tous les autres changements.Vous devez manuellement attraper les exceptions à l'extérieur de la transaction si la validation échoue.
Tout ce que je dis, c'est: vous un peu, deux choix s'offrent a) gérer la validation à droite après le
save
à l'aide de la valeur de retour b) de laisser le processus de tâche plantage lors de l'utilisationsave!
, il y a (dans presque tous les cas), pas de terrain d'entente. Un seulsave
(sans manipulation de sa valeur de retour) est un grand signe d'avertissement. La transaction s'assure juste que tout le reste est rétabli.Pour le mettre différemment: Votre exemple est presque TOUJOURS jamais ce que vous voulez. Si l'un de vos objets dans
a
ne peut pas être sauvée, le tas ne sera pas enregistré. Après la transaction de bloc que vous ne connaissez pas: a) si les objets ont été enregistrés, b) si non, qui a causé la restauration c) quel était le problème. Je ne peux pas imaginer une situation où je veux ce comportement.Revenir tous les jets de sauvegarde si l'un tombe en panne est le but de l'utilisation d'une transaction. Comment le processus de l'échec/réussite est une bonne question à laquelle je ne vois pas une bonne réponse, parce que
transaction
méthode ne semble pas revenir en tant que valeur. Il me ressemble unActiveRecord
faille.OriginalL'auteur Alexey
Dans le cas où vous êtes à la recherche d'une solution plus efficace que d'enregistrer chaque ligne dans la boucle s'il vous plaît regardez ma réponse ici Ruby on Rails - Importer des Données à partir d'un fichier CSV
Je suggère d'utiliser le gem
activerecord-import
.OriginalL'auteur Yaroslav