2011-07-17 9 views
2

私のアプリでは、多くの会話があり、会話には多くのメッセージがあります。私は新しい会話を作りたい:ユーザ(読者)と(最初の)メッセージを指定しなければならない。私は以下を試しましたが、失敗しました。Rails:ネストされたモデルのフォームでaccepts_nested_attributes_forを使用する

モデル

class Conversation < ActiveRecord::Base 

    has_many :conversation_users 
    has_many :users, :through => :conversation_users 

    has_many :messages 

    accepts_nested_attributes_for :users 
    accepts_nested_attributes_for :messages 

end 

class Message < ActiveRecord::Base 

    belongs_to :conversation 
    belongs_to :user 

end 

class User < ActiveRecord::Base 

    has_many :conversation_users 
    has_many :conversations, :through => :conversation_users 

end 

コントローラ

def new 
    @conversation = Conversation.new 
    2.times do 
    users = @conversation.users.build 
    end 
    messages = @conversation.messages.build 
end 

def create 
    @conversation = Conversation.new(params[:conversation]) 

    if @conversation.save 
    redirect_to username_conversations_path(current_username) 
    else 
    redirect_to new_username_conversation_path(current_username) 
    end 
end 

ビュー

<% form_for([current_user, @conversation]) do |f| %> 

    <% f.fields_for :users do |builder| %> 

    <%= builder.text_field :id %> 

    <% end %> 

    <% f.fields_for :messages do |builder| %> 

    <%= builder.text_area :content %> 

    <% end %> 

    <%= f.submit "Submit" %> 

<% end %> 

次のようにCURRENT_USERとcurrent_usernameは、定義されたヘルパーメソッドです:

def current_user 
    @current_user ||= User.find(session[:user_id]) if session[:user_id] 
end 

def current_username 
    @current_username ||= current_user.username if current_user 
end 

これは、サーバーの応答をレール:conversations_controllerの

Started POST "https://stackoverflow.com/users/8/conversations" for 127.0.0.1 at Sun Jul 17 23:58:27 +0200 2011 
    Processing by ConversationsController#create as HTML 
    Parameters: {"commit"=>"Submit", "authenticity_token"=>"z6kL+NmVspgCKMr9whcw+a85mA59j3jssS9QeTiEbxc=", "utf8"=>"✓", "conversation"=>{"users_attributes"=>{"0"=>{"id"=>"9"}, "1"=>{"id"=>"10"}}, "messages_attributes"=>{"0"=>{"content"=>"freee"}}}, "user_id"=>"8"} 
    User Load (0.3ms) SELECT "users".* FROM "users" INNER JOIN "conversation_users" ON "users".id = "conversation_users".user_id WHERE "users"."id" IN (9, 10) AND (("conversation_users".conversation_id = NULL)) 

ActiveRecord::RecordNotFound (Couldn't find User with ID=9 for Conversation with ID=): 
    app/controllers/conversations_controller.rb:26:in `new' 
    app/controllers/conversations_controller.rb:26:in `create' 

行26:@conversation = Conversation.new(params[:conversation])

どのように私はこの仕事を得ることができますか?

ありがとうございました。

+0

「失敗しました」とはどういう意味ですか?エラーはありますか? – fl00r

+0

エラー応答を追加しました...レコードが見つかりませんでした – alste

+0

あなたの応答にエラーが表示されません – fl00r

答えて

6
class Conversation < ActiveRecord::Base 
    has_many :conversation_users 
    has_many :users, :through => :conversation_users 
    has_many :messages 
    # NEXT LINE IS CHANGED! 
    accepts_nested_attributes_for :conversation_users 
    accepts_nested_attributes_for :messages 
end 

コントローラでなければなりません

def new 
    @conversation = Conversation.new 
    2.times{ users = @conversation.conversation_users.build } 
    messages = @conversation.messages.build 
end 

そして、それだ形

<%= form_for([current_user, @conversation]) do |f| %> 
    <%= f.fields_for :conversation_users do |builder| %>  
    <%= builder.text_field :user_id %> 
    <%= builder.hidden_field :conversation_id %> 
    <% end %> 
    ... 
<% end %> 

+0

右、私は新しい 'conversation_user'オブジェクトを作成しています「ユーザ」オブジェクト!素晴らしい:)あなたの助けに感謝 – alste

1

は交換してください:

   <% f.fields_for :users do |builder| %> 

で:

   <%= f.fields_for :users do |builder| %> 

ビット下の '=' 行方不明と同じ。

+0

- フォームがうまく表示されていました...エラーは私の前に – alste

1
<% form_for([current_user, @conversation]) do |f| %> 

<%= form_for([current_user, @conversation]) do |f| %> 

そして

<% f.fields_for :messages do |builder| %> 
# and 
<% f.fields_for :users do |builder| %> 

する必要がありますが

<%= f.fields_for :messages do |builder| %> 
# and 
<%= f.fields_for :users do |builder| %> 
+0

+1の4秒前に私の前に: – apneadiving

+0

@apneadiving実際には逆: – fl00r

+0

しかし、エラーが残ります - 私はエラーの詳細を追加 – alste

関連する問題