Two models,ProductAndCategory; There arehas_and_belongs_to_manyYou are expected to edit the relationship between the project and the category when editing the project. The project editing interface is as follows:
Add checkboxes
check_boxAndcheck_box_tagYou can add checkboxes to the form. Because you need to override the name of the checkbox, selectcheck_box_tag, Edit the project code as follows:
ruby" style="clear: both;<% for category in Category.find(:all) %> <div> <%= check_box_tag "product[category_ids][]", category.id, @product.categories.include?(category) %> <%= category.name %> </div><% end %>
check_box_tagThe name, value, and whether the checkbox parameters are selected are required, and the reason why the name is so named is explained. Seeing if it works
After execution, I found that the selected content has been updated after submission. How does rails work? The following log will give the answer:
terminalProcessing ProductsController#update (for 127.0.0.1 at 2009-01-15 20:57:56) [PUT]Parameters: {"commit"=>"Edit", "authenticity_token"=>"31b711f2c24ae7cea5abf3f758eef46b472eebf3", "product"=>{"price"=>"99.0", "name"=>"Television Stand", "category_ids"=>["2", "4"]}, "id"=>"1"}
After submission, edit form places the category parameter in the project hash and passes it as an array. Setting the name of checkboxes to project [category_ids] [] is the key to normal operation. The first part of the name tells rails category_ids that it will be part of the project hash. The second part of the name [] indicates that the transfer method is array. When updating a project, where does the category_ids method come from? From project modelhas_and_belongs_to_many. Inscript/consoleThe manually updated log in is as follows:
terminal>> p = Product.first=> #<Product id: 1, name: "Television Stand", price: 99.0, created_at: "2009-01-11 21:32:12", updated_at: "2009-01-11 21:32:12">>> p.category_ids=> [2, 3]>> p.category_ids = [1,4]=> [1, 4]>>
The SQL statement is as follows:
sqlDELETE FROM "categories_products" WHERE product_id = 1 AND category_id IN (2,3)INSERT INTO "categories_products" ("product_id", "id", "category_id") VALUES (1, 1, 1)INSERT INTO "categories_products" ("product_id", "id", "category_id") VALUES (1, 4, 4)A small problem
There is still a small problem in the update method. If you do not select any items in the checkboxes, all the category operations corresponding to the project will fail. The main reason is that if checkboxes is not selected,category_idsWill not appear in the product parameter, meaningcategory_idsWill not be updated.
You can use the | = operation of Ruby to solve this problem.
params[:product][:category_ids] ||= []
This ensures that when the category is not selected, set Params [: product] [: category_ids] to null to update the category.
Http://railscasts.com/episodes/17-habtm-checkboxes? View = asciicast
Railscasts17 habtm checkboxes update the many-to-many relationship