所以我有两个模型Topic
,Client
。客户has_and_belongs_to_many :topics
和主题has_and_belongs_to_many :clients
。
基本上,我想要发生的事情是...当有人去我的Topic#index
时,取决于他们如何到达那里(即通过client/:id/topics
或/topics
),我想要创造和放大的行为新的不同。即在/topics
,它只是创建一个主题。在client/:id/topics
,它会创建一个主题并将其分配给该客户。
我的路线看起来像这样:
resources :topics
resources :clients do
resources :topics
end
My Topics Controller看起来像这样:
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
我的views/topics/_form.html.erb
看起来像这样:
<%= form_for([@client, @topic]) do |f| %>
...
<% end %>
但是,当我从client/:id/topics
执行操作时,这就是日志的样子:
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)
看起来不错......这里的一切似乎都井井有条。但是在POST
中似乎没有工作:
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)
您会注意到没有为客户分配新主题。
我错过了什么?
谢谢!
修改1
添加了将调试语句放到我的创建操作中,这是我在执行POST操作后得到的结果 - 这表明获得了params[:client_id]
而不仅仅是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)
编辑2:
所以我尝试了其他似乎有效的方法,但我很想知道为什么上述方法不起作用。
如果,在我的Topic#create
我就这样做了:
@client = Client.find(params[:client_id])
@topic = Topic.new(params[:topic])
@client.topics << @topic
工作正常。
但是,再次......我很想知道为什么.build
不适合HABTM或在这种情况下。
答案 0 :(得分:1)
我认为问题出在params[:client_id]
,可能是params[:id]
。
您是否可以在if else创建操作块中添加puts
语句,然后查看当您点击页面时显示的内容(创建主题)
修改强>
您需要在模型中包含 accepts_nested_attributes_for ,以支持动态构建嵌套对象属性。
参考this。
答案 1 :(得分:0)
似乎我必须在我的@client
对象上完成构建后显式调用save。
否则,ActiveRecord将不保存事务并在join_table中插入新记录。