Rails HABTM 复选框不保存到数据库
我正在开始 Rails 编程,我想要完成的就是拥有一个复选框列表,我可以从中选择产品的相应类别。 我在这件事上关注了railscast,但它似乎对我不起作用。
我使用 Rails 3.0.9 和 Ruby 1.8.7。
我已经正确设置了模型以及连接表的迁移。 当我尝试编辑产品时,category_ids 会被发布,但它们永远不会保存到数据库中。
日志:
Started POST "/products/1" for 127.0.0.1 at Mon Sep 19 01:39:33 +0300 2011
Processing by ProductsController#update as HTML
Parameters: {"commit"=>"Update Product", "authenticity_token"=>"x2Z5GGiNh9yLz6xjuQaMqdGW3Gw7dYe8dSghyrFpiYk=", "utf8"=>"���", "id"=>"1", "product"=>{"name"=>"Magicianulx2", "price"=>"121", "category_ids"=>["1"]}}
Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."id" = 1 LIMIT 1
WARNING: Can't mass-assign protected attributes: category_ids
Redirected to http://localhost:3000/products/1
Completed 302 Found in 10ms
Started GET "/products/1" for 127.0.0.1 at Mon Sep 19 01:39:33 +0300 2011
Processing by ProductsController#show as HTML
Parameters: {"id"=>"1"}
Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."id" = 1 LIMIT 1
Rendered products/show.html.erb within layouts/application (4.2ms)
Completed 200 OK in 11ms (Views: 6.1ms | ActiveRecord: 0.2ms)
模型:
class Product < ActiveRecord::Base
attr_accessible :name, :price
has_and_belongs_to_many :categories
end
class Category < ActiveRecord::Base
attr_accessible :name
has_and_belongs_to_many :products
end
迁移:
class AddCategoriesProducts < ActiveRecord::Migration
def self.up
create_table :categories_products, :id => false do |t|
t.integer :category_id
t.integer :product_id
end
end
def self.down
drop_table :categories_products
end
end
控制器(产品控制器中的更新方法)
def update
@product = Product.find(params[:id])
if @product.update_attributes(params[:product])
redirect_to @product, :notice => "Successfully updated product."
else
render :action => 'edit'
end
end
视图/产品中的我的_form.html.erb
<%= form_for @product do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.label :price %><br />
<%= f.text_field :price %>
</p>
<% for category in Category.find(:all) %>
<div>
<%= check_box_tag "product[category_ids][]", category.id, @product.categories.include?(category) %>
<%= category.name %>
</div>
<% end %>
<p><%= f.submit %></p>
<% end %>
控制器和视图都是使用漂亮的脚手架生成的。 其他一切似乎都工作正常,但复选框中的值不会保存到数据库中。 通过 Rails 控制台手动添加它们效果很好。 关于我做错了什么有什么想法吗?
I am beginning Rails programming and all I want to accomplish is to have a list of check boxes from which I can choose the corresponding categories for a product.
I have followed the railscast on this matter, but it doesn't seem to work for me.
I work with Rails 3.0.9 and Ruby 1.8.7.
I have the models properly set up and the migration for the join table as well.
When I try to edit a product, the category_ids get POSTed, but they are never saved to the database.
Log :
Started POST "/products/1" for 127.0.0.1 at Mon Sep 19 01:39:33 +0300 2011
Processing by ProductsController#update as HTML
Parameters: {"commit"=>"Update Product", "authenticity_token"=>"x2Z5GGiNh9yLz6xjuQaMqdGW3Gw7dYe8dSghyrFpiYk=", "utf8"=>"���", "id"=>"1", "product"=>{"name"=>"Magicianulx2", "price"=>"121", "category_ids"=>["1"]}}
Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."id" = 1 LIMIT 1
WARNING: Can't mass-assign protected attributes: category_ids
Redirected to http://localhost:3000/products/1
Completed 302 Found in 10ms
Started GET "/products/1" for 127.0.0.1 at Mon Sep 19 01:39:33 +0300 2011
Processing by ProductsController#show as HTML
Parameters: {"id"=>"1"}
Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."id" = 1 LIMIT 1
Rendered products/show.html.erb within layouts/application (4.2ms)
Completed 200 OK in 11ms (Views: 6.1ms | ActiveRecord: 0.2ms)
Models :
class Product < ActiveRecord::Base
attr_accessible :name, :price
has_and_belongs_to_many :categories
end
class Category < ActiveRecord::Base
attr_accessible :name
has_and_belongs_to_many :products
end
Migration :
class AddCategoriesProducts < ActiveRecord::Migration
def self.up
create_table :categories_products, :id => false do |t|
t.integer :category_id
t.integer :product_id
end
end
def self.down
drop_table :categories_products
end
end
Controller (update method in product controller)
def update
@product = Product.find(params[:id])
if @product.update_attributes(params[:product])
redirect_to @product, :notice => "Successfully updated product."
else
render :action => 'edit'
end
end
My _form.html.erb in views/products
<%= form_for @product do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.label :price %><br />
<%= f.text_field :price %>
</p>
<% for category in Category.find(:all) %>
<div>
<%= check_box_tag "product[category_ids][]", category.id, @product.categories.include?(category) %>
<%= category.name %>
</div>
<% end %>
<p><%= f.submit %></p>
<% end %>
The controllers and the views were all generated using nifty scaffolding.
Everything else seems to work just fine, but the values from the check boxes don't get saved to the database.
Adding them by hand via the rails console works just fine.
Any ideas on what I am doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的产品模型具有
attr_accessible :name, :price
,因此当您尝试执行操作时,日志会显示
在你的控制器中。警告:无法批量分配受保护的属性:category_ids
@product.update_attributes(params[:product])尝试将
category_ids
添加到attr_accessible
。Your Product model has
attr_accessible :name, :price
and that's why the log showsWARNING: Can't mass-assign protected attributes: category_ids
when you try to do@product.update_attributes(params[:product])
in your controller.Try adding
category_ids
toattr_accessible
.当我做了或多或少相同的事情时,我的
check_box_tag
看起来有所不同:我最终不需要需要
attr_accessible
,尽管正如我在 < a href="http://buckybits.blogspot.com/2011/08/associating-hasmany-relationships-in.html" rel="nofollow">我的博客文章描述了完全相同的内容事情,我仍然不确定为什么不。我还使用了has_many:through
。When I did more or less the same thing, my
check_box_tag
looked different:I ended up not needing the
attr_accessible
, although as I mention in my blog post describing the exact same thing, I'm still not sure why not. I also usedhas_many:through
.