这一节,我们讨论一下has_and_belongs_to_many 这个方法和与之相关的checkbox的应用:
在本节的例子中,我们有两个模型,product和category,他们之间是has_and_belongs_to_many的关系。
我们要在一个页面通过checkboxes编辑一个product所属的categories。
有两个方法可以用,check_box 和 check_box_tag, 这里我们使用check_box_tag, 因为用他我们可以控制checkbox的名字。
我们的代码如下:
<%for category in Catogery.find(:all)%>
<%=check_box_tag "product[category_ids][]", catogery.id, @product.catogery.include(category)%>
<%=category.name%>
<%end%>
可以看到,我们这里check_box_tag接收了3个参数,第一个参数是name,第二个参数是value,第三个参数是boolean值,用来标记这个checkbox是否被check了。
当我们保存这个product的时候,得到了一下的log:
Parameters: {"commit"=>"Edit", "authenticity_token"=>"31b711f2c24ae7cea5abf3f758eef46b472eebf3", "product"=>{"price"=>"99.0", "name"=>"Television Stand", "category_ids"=>["2", "4"]}, "id"=>"1"}
关键是这里:
"category_ids"=>["2", "4"]
这就是我们的第一个参数的作用,这个参数的第一部分告诉rails,category_ids是hash的一部分,而空的数组告诉rails,这个参数是一个数组,但是category_ids 这个方法是哪里来的呢? 他就是我们的has_and_belong_to_many 这个声明生成的一个方法。例如:
>> p = Product.first
=> #
>> p.category_ids
=> [2, 3]
>> p.category_ids = [1,4]
=> [1, 4]
在内部sql部分,是这样执行的:
- DELETE 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)
但是以上做法有一个小小的问题,就是如果所有的checkbox都没有被check,那么提交的时候,参数中就没有catogery_ids 这个部分,那么catogery就不会被更新,解决方法就是在update方法中,加入如下一行:
param[:product][:category_ids] ||= []
阅读(436) | 评论(0) | 转发(0) |