collection_check_boxes的应用

table中要用一组checkbox来实现多选勾选,最初简单的想法是用一个:house_options来作为栏位,勾选的内容全部放在这个栏位里面。之所以这样想,是因为

<%= f.input :house_options ,collection:["个人出租住宅","品牌公寓","别墅","商铺","车库"],label:"房屋类型",as: :check_boxes %>

以上代码能实现这样:

于是使用这种方式,提交到服务端的参数格式为:

2.3.1 :013 > g.house_options
 => "[\"\", \"品牌公寓\", \"别墅\", \"商铺\"]" 

在显示界面要显示用户的房屋类型选择,如果直接用<%= @guest.house_options%>的话,显示结果就是:

["","品牌公寓","别墅","商铺"]

显然这是非常丑的,于是为了美化显示结果,用了gsub()方法,来把多余的符号去掉。gsub参考。

class Guest < ApplicationRecord
    def show_option(option)
        option.gsub!(/[\[\]]/,'');//去掉大括号
        option.gsub!(/[\"]/,'');//去掉引号
        option.gsub!(/\,/,' ');//去掉逗号
    end
2.3.1 :020 > a.gsub!(/[\[\]]/,'')
 => "\"\", \"品牌公寓\", \"别墅\", \"商铺\""
2.3.1 :021 > a.gsub!(/[\"]/,'')
 => ", 品牌公寓, 别墅, 商铺"
 [1] pry(#)> option.gsub!(/\,/,' ')
=> "  品牌公寓  别墅  商铺"
<% if @guest.house_options.present? %> <%= @guest.show_option(@guest.house_options) %> <%end%>

完成以上后美滋滋的保存代码,终于还记得检查一下效果,于是点开edit界面,发现原先选择的check box又重置了,都没有选中。
猜测原因是house_options输入的是string,无法更新check_box的状态。
尝试过使用:

 <%= f.input :house_options ,collection:[["个人出租住宅",0],["品牌公寓",1],["别墅",2],["商铺",3],["车库",4]],label:"房屋类型",as: :check_boxes %>

但是这样的结果只是把显示的["","品牌公寓","别墅","商铺"]变成了["","0","1","2"],并不能解决问题。

中间又查找check_box的默认状态,消耗了一些时间,直到找到collection_check_boxes

collection_check_boxes

collection_check_boxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block) public

Returns check box tags for the collection of existing return values of method for object's class. The value returned from calling method on the instance object will be selected. If calling method returns nil, no selection is made.

The :value_method and :text_method parameters are methods to be called on each member of collection. The return values are used as the value attribute and contents of each check box tag, respectively. They can also be any object that responds to call, such as a proc, that will be called for each member of the collection to retrieve the value/text.

参数解说
object是对象
method用来设置选中
collection是check_boxes勾选内容
value_method是check_box的value值
text_method是check_box要显示的勾选内容

举例说明collection_check_boxes

创建option 和 guest_option两个model,guest通过guest_option和option建立多对多的关联。option只需要一个:content栏位。

按照上面关系创建model并关联。

class Guest < ApplicationRecord
  has_many :guest_options
  has_many :options,through: :guest_options
  ...

其它关联代码啊省略。。。
form的代码变更为:

<%= f.collection_check_boxes :option_ids,Option.all,:id,:content %>

method参数是:option_ids,于是可以有默认选中功能了
collection参数是Option.all,所以要有option这个model,栏位:content,用来做勾选项目的显示文字
value_method参数是:id,这里以option的id作为value值

编辑controllers/backend/guests_controller.rb,添加:option_ids=>[]permit()方法里。

console查看提交的option_ids参数:

"option_ids"=>["", "1", "4", "5"]

页面要显示选中的房屋类型就不需要再做字符串变换了:


  <% if @guest.options.any? %>
    <% @guest.options.each do |option|%>
      <%= option.content %>
    <% end %>
  <% end %>


你可能感兴趣的:(ruby)