It is often asked: how do I create a list of checkboxes for managing a HABTM association? Ask no more because this episode will show you how to do exactly that.
经常出现这样一个问题:我如何创建一个多选框列表来实现has_and_belongs_to_many(多对多)的关系?这节就来具体解决这个问题。
首先,有两个实体:
Category和product,很显然它们是多对多的关系:
#category.rb
class Category < ActiveRecord::Base
has_and_belongs_to_many :products
end
#product.rb
class Product < ActiveRecord::Base
has_and_belongs_to_many :categories
end
现在在表单中,譬如对于product的表单:
<p>
Name<br/>
<%= text_field :product, :name%>
</p>
<p>
<% Category.find(:all).each do |category|%>
<div>
<%= check_box_tag "product[category_ids][]", category.id, @product.categories.include?(category)%>
<%= category.name%>
</div>
<% end %>
</p>
在日志中:
Parameters:{"commit"=>"Edit", "product"=>{"name"=>"Television Stand", "category_ids"=>["1","3"]},"action"=>"update", "id"=>"1","controller"=>"products" }
category_ids是product和category多对多关联的一个属性,在console下product.category_ids是一个数组。
但是对于has_many ,through关系来说,这个xxx_ids属性就得手动写了。
此时,如果是edit多选框,取消所有已选框,不会发生变化,因为提交的时候没有category_ids参数了。所以,在controller的update action中要加一个语句:
def update
params[:product][:category_ids] ||=[]
...
end
这样当没有这个参数提交的时候就将其设为空数组。
相关内容可参见我的另一篇文章
<%check_box%> in rails :coditions=>{:has_many , :through}
----------------------下面是railsbrain中check_box方法的描述:
check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
Returns a checkbox tag tailored for accessing a specified attribute (identified by
method) . an object assigned to the template (identified by
object). It’s intended that
method
returns an integer and if that integer is above zero, then the checkbox is checked. Additional options . the input tag can be passed as a hash with
options. The
checked_value
defaults to 1 while the default
unchecked_value
is set to 0 which is convenient for boolean values. Since HTTP standards say that unchecked checkboxes don’t post anything, we add a hidden value with the same name as the checkbox as a work around.
Examples
# Let's say that @post.validated? is 1: check_box("post", "validated") # => <input type="checkbox" id="post_validated" name="post[validated]" value="1" /> # <input name="post[validated]" type="hidden" value="0" /> # Let's say that @puppy.gooddog is "no": check_box("puppy", "gooddog", {}, "yes", "no") # => <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" /> # <input name="puppy[gooddog]" type="hidden" value="no" /> check_box("eula", "accepted", { :class => 'eula_check' }, "yes", "no") # => <input type="checkbox" class="eula_check" id="eula_accepted" name="eula[accepted]" value="yes" /> # <input name="eula[accepted]" type="hidden" value="no" />下面是对check_box_tag的描述:
check_box_tag(name, value = "1", checked = false, options = {})
Creates a check box form input tag.
Options
- :disabled - If set to true, the user will not be able to use this input.
- Any other key creates standard HTML options for the tag.
Examples
check_box_tag 'accept' # => <input id="accept" name="accept" type="checkbox" value="1" /> check_box_tag 'rock', 'rock music' # => <input id="rock" name="rock" type="checkbox" value="rock music" /> check_box_tag 'receive_email', 'yes', true # => <input checked="checked" id="receive_email" name="receive_email" type="checkbox" value="yes" /> check_box_tag 'tos', 'yes', false, :class => 'accept_tos' # => <input class="accept_tos" id="tos" name="tos" type="checkbox" value="yes" /> check_box_tag 'eula', 'accepted', false, :disabled => true # => <input disabled="disabled" id="eula" name="eula" type="checkbox" value="accepted" />
转载于:https://blog.51cto.com/fsjoy/131674