How do I get my create action to work for both a nested & non-nested resource?

So I have two models Topic, Client. A Client has_and_belongs_to_many :topics, and a Topic has_and_belongs_to_many :clients.

Basically, what I want to happen is...when someone goes to my Topic#index, depending on how they got there (i.e. either via client/:id/topics or just /topics), I want the behavior of the create & new to be different. i.e. at /topics, it just creates a topic. At client/:id/topics it creates a topic and assigns it to that client.

My routes look like this:

  resources :topics
  resources :clients do
    resources :topics
  end

My Topics Controller looks like this:

  def new
        if params[:client_id]
            @client = Client.find(params[:client_id])
            @topic = @client.topics.build
        else
            @topic = Topic.new
        end

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @topic }
    end
  end

  def create
        if params[:client_id]
            @client = Client.find(params[:client_id])
            @topic = @client.topics.build(params[:topic])
        else
        @topic = Topic.new(params[:topic])
        end

    respond_to do |format|
      if @topic.save
        format.html { redirect_to @topic, notice: 'Topic was successfully created.' }
        format.json { render json: @topic, status: :created, location: @topic }
      else
        format.html { render action: "new" }
        format.json { render json: @topic.errors, status: :unprocessable_entity }
      end
    end
  end

My views/topics/_form.html.erb looks like this:

<%= form_for([@client, @topic]) do |f| %>
...
<% end %>

However, when I perform an action from client/:id/topics this is what the logs look like:

Started GET "/clients/1/topics/new" for 127.0.0.1 at 2012-09-10 14:33:06 -0500
Processing by TopicsController#new as HTML
  Parameters: {"client_id"=>"1"}
  Client Load (0.2ms)  SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT 1  [["id", "1"]]
  Rendered topics/_form.html.erb (3.6ms)
  Rendered topics/new.html.erb within layouts/application (4.7ms)
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
   (0.2ms)  SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = 1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL)))
  Rendered layouts/_navigation.html.erb (7.2ms)
  Rendered layouts/_messages.html.erb (0.1ms)
Completed 200 OK in 61ms (Views: 57.0ms | ActiveRecord: 0.7ms)

That looks good...everything seems to be in order here. But it is in the POST that things seem to be not working:

Started POST "/clients/1/topics" for 127.0.0.1 at 2012-09-10 14:33:13 -0500
Processing by TopicsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"J172LuZQPv8=", "topic"=>{"name"=>"AMZN"}, "commit"=>"Create Topic", "client_id"=>"1"}
  Client Load (0.2ms)  SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT 1  [["id", "1"]]
   (0.1ms)  begin transaction
  SQL (186.2ms)  INSERT INTO "topics" ("created_at", "name", "updated_at") VALUES (?, ?, ?)  [["created_at", Mon, 10 Sep 2012 19:33:13 UTC +00:00], ["name", "AMZN"], ["updated_at", Mon, 10 Sep 2012 19:33:13 UTC +00:00]]
   (4.6ms)  commit transaction
Redirected to http://localhost:3000/topics/4
Completed 302 Found in 198ms (ActiveRecord: 191.1ms)

You will notice there is no assignment of the new topic to the client.

What am I missing?

Thanks!

Edit 1

Added puts debug statements to my create action, and this is the result I got after the POST action was executed - which indicates that is getting the params[:client_id] and not just params[:id]:

Served asset /application.js - 304 Not Modified (1ms)
**************************************************
This is the params[:client_id] => {3}
**************************************************
This is the params[:id] => {}


Started POST "/clients/3/topics" for 127.0.0.1 at 2012-09-10 15:06:31 -0500
Processing by TopicsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"J172LuZQc5NYoiMSzDD3oY9vGmxxCX0OdxcGm4GSPv8=", "topic"=>{"name"=>"TEST2"}, "commit"=>"Create Topic", "client_id"=>"3"}
  Client Load (0.2ms)  SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT 1  [["id", "3"]]
   (0.1ms)  begin transaction
  SQL (0.7ms)  INSERT INTO "topics" ("created_at", "name", "updated_at") VALUES (?, ?, ?)  [["created_at", Mon, 10 Sep 2012 20:06:31 UTC +00:00], ["name", "TEST2"], ["updated_at", Mon, 10 Sep 2012 20:06:31 UTC +00:00]]
   (3.3ms)  commit transaction
Redirected to http://localhost:3000/topics/6
Completed 302 Found in 11ms (ActiveRecord: 4.3ms)

Edit 2:

So I tried something else that seems to work, but I would love to know why the above doesn't work.

If, in my Topic#create I just do this:

@client = Client.find(params[:client_id])
@topic = Topic.new(params[:topic])
@client.topics << @topic

It works fine.

But, again...I would love to know why the .build doesn't for HABTM or in this situation.

Answers


I think the issue is in the params[:client_id] it may be params[:id].

Can you put a puts statement in your if else block of create action, and then see which one is showing up when you hit the page(create a topic)

EDIT

You need to include accepts_nested_attributes_for in your model to support dynamic building of nested object attributes.

Refer this.


Need Your Help

button click event is not fired when pop up is opened

c# javascript ado.net sqlclient

i am working on a website in aspx in which i need a pop up. i have a pop up which i want to use it in site.

weka confusion matrix and accuracy analysis

data data-mining weka confusion-matrix

How do I analyze the confusion matrix in Weka with regards to the accuracy obtained?

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.