9
votes

Est possible de sauvegarder récursivement un enregistrement dans les rails?

Par exemple, utilisateur a une liste , list a beaucoup article s, et j'ai ce qui suit Code dans le contrôleur: xxx

maintenant si j'appelle @ user.save , @List et 10 élément > S ne serait pas enregistré dans la base de données. Comment dois-je réécrire ce code?


4 commentaires

Avez-vous trouvé une réponse pour cela?


@ Magne Oui, il est possible de sauvegarder des modèles récursivement. Si vous avez du mal à vérifier cela: API.RubyonRails.org/classes/acterecord/... s'il y a encore quelque chose de mal, puis postez vos modèles, associations et vos cas simples. L'article original n'a aucune information sur les relations des modèles.


Merci @flashgordon!


Après avoir appelé @ user.save , y a-t-il des erreurs sur le modèle? C'est-à-dire quelle est la valeur de @ user.Errors à ce point? Quelle est la valeur de @ user.list.errors ?


6 Réponses :


2
votes

Je pense que vous voulez dire @ user.list = @List .

Après cela, appeler @ user.save devrait tout sauver.


1 commentaires

Mais si @List ne peut pas passer les validations, comment puis-je le savoir? @ user.save retourne toujours true et @ user.save! ne soulève rien.



0
votes

Si vous avez de nombreuses listes d'un utilisateur, vous pouvez utiliser les listes HAS_MANY: Listes du modèle utilisateur. Ensuite, la table doit avoir une colonne user_id.

Dans le contrôleur, vous pouvez obtenir toutes les listes d'un utilisateur à l'aide de User.Listes qui retourneront la liste des listes de cet utilisateur. Vous pouvez ajouter plus de liste à l'utilisateur comme utilisateur.LISTES << NEW_LIST.

Je pense que c'est ce que vous cherchiez.


0 commentaires

1
votes

Vous pouvez configurer Activerecord à Cascade-Enregistrer les modifications des éléments d'une collection pour un modèle en ajoutant: autosave => option vraie lors de la déclaration de l'association. En savoir plus .

Exemple: P>

class Payment < ActiveRecord::Base
    belongs_to :cash_order, :autosave => true
    ...
end


0 commentaires

0
votes

rails sait comment gérer cela. Il existe plusieurs manières en fonction de votre conception, et si je comprends bien, vous devez soulever une exception lorsqu'une erreur de validation se produit. Essayez ceci:

ActiveRecord::Base.transaction do
  @user = User.new(name: 'example')
  @user.create_list!(label: 'something')
  (1..10).each {|i| @user.list.items.create!(order: i) } 
  @user.save!
end


0 commentaires

10
votes

En configurant des associations et des validations appropriées Vous pouvez vous assurer que lorsque vous enregistrez l'utilisateur, la liste associée et les éléments sont enregistrés en même temps. De plus, vous pouvez vous assurer que tout est enregistré dans une seule transaction et que la sauvegarde sera abandonnée si un enregistrement d'enfant ne peut pas être enregistré.

Compte tenu des définitions de modèle suivantes pour l'utilisateur, la liste et l'élément P>

(0.2ms)  BEGIN
SQL (0.3ms)  INSERT INTO `lists` (`name`) VALUES ('My list')
SQL (0.1ms)  INSERT INTO `items` (`list_id`, `name`) VALUES (4, 'Widget')
SQL (0.3ms)  INSERT INTO `users` (`list_id`) VALUES (4)
(0.3ms)  COMMIT


3 commentaires

Notez que validateate_associated ne fonctionne pas avec has_one . Pour cela, vous devriez écrire has_one: classname, valide: true . Réf: apidock.com/rails/acterecord/validations/classmethods/.../a>


@Magne, ma solution n'utilise pas une association has_one . Est-ce ce que vous utilisez?


Oui, c'est ce que j'utilisais.