2

In my app, Users have many Conversations, and Conversations have many Messages. I want to create a new Conversation: I have to specify the Users (readers) and the (first) Message. I tried the following, but it failed.

Models

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

Controller

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

View

<% 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 and current_username are helper methods defined as follows:

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

This is rails server's response:

Started POST "/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'

line 26 of conversations_controller: @conversation = Conversation.new(params[:conversation])

How can I get this to work?

Thanks.

7
  • what do you mean "failed"? Any errors? Commented Jul 17, 2011 at 22:20
  • I added the error reponse... it's a record not found error Commented Jul 17, 2011 at 22:21
  • i can't see any error in your response Commented Jul 17, 2011 at 22:27
  • what is current_username? show this helper code Commented Jul 17, 2011 at 22:45
  • current_username is the username of the currently logged in user. current_user returns the currently logged in user (in both cases, the user who is creating a new conversation) Commented Jul 18, 2011 at 7:14

3 Answers 3

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

Controller

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

And form

<%= 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 %>

That's it.

Sign up to request clarification or add additional context in comments.

1 Comment

right, I'm creating a new 'conversation_user' object, not a 'user' object! wonderful :) thanks for your help
1

Replace:

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

With:

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

Same missing '=' a bit lower.

Comments

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

should be

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

And

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

should be

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

1 Comment

@apneadiving actualy vice versa :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.