2010-11-24 4 views
0

J'ai deux modèles:Rails - Création d'enregistrements de modèle parent et imbriqué?

class Conversation < ActiveRecord::Base 
    has_many :conversation_participations 
end 

class ConversationParticipation < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :conversation 
end 

En ce moment, je fais des documents en faisant quelque chose comme:

@conversation = Conversation.create(......) 
    conversation = @conversation.save 

    params[:users].each do |user| 
    @user = User.find(user.to_i) 
    conversation_participation = @recipient.conversation_participations.find_or_create_by_conversation_id(@conversation.id) 
    conversation_participation.save 
    end 

Le problème est que je dois les conversation_participations à tous, sauf en même temps, pas un à la fois. Comment puis-je faire cela avec Rails? Construire une conversation et des participations et sauvegarder tout à la fois?

Répondre

1

conversation_participations est soit un UPDATE, soit un INSERT. Il n'y a pas de détermination jusqu'à ce que le code fonctionne réellement. Et même dans ce cas, certaines bases de données peuvent ne pas prendre en charge plusieurs insertions. Ce que vous voulez ressemble à une transaction. Une transaction peut être créée dans Rails en utilisant la méthode transaction de n'importe quel modèle, qui prend un bloc. (Et il ne compte pas vraiment le modèle que vous appelez sur, il applique à toutes les opérations de base de données dans ce bloc.)

En gros:

Conversation.transaction do 
    @conversation = Conversation.create(......) 
    # ...etc... 
end 

Vous voulez vous assurer que votre base de données prend en charge les transactions . Vous n'avez pas spécifié le système de base de données que vous utilisez, mais MySQL, par exemple, transforme les transactions en no-ops pour le backend MyISAM. Si vous utilisez MySQL, assurez-vous que vos tables sont InnoDB. (Je crois que si vos tables ont été créées en utilisant Rails, elles le seront, mais il vaut mieux revérifier.)

Questions connexes