【问题标题】:Display a checkbox list instead of multiple select显示复选框列表而不是多选
【发布时间】:2013-04-09 10:31:58
【问题描述】:

我有一个模型MyModel,带有一个序列化属性a,描述了一个符号数组。

此代码有效:

<% form_for @my_model do |f| %>
  <%= f.select :a, MyModel::AS, :multiple => true) %>
<% end %>

参数正确:

{ :my_model => { :a => [:a_value1, :a_value2] } }

我想把这个多选转换成一组复选框,像这样:

<% form_for @my_model do |f| %>
  <% MyModel::AS.each do |a_value|
    <%= f.check_box(:a_value) %>
  <% end %>
<% end %>

也可以,只是参数完全不一样:

{ :my_model => { :a_value1 => 1, :a_value2 => 1 } }

我想到了2个解决方案返回第一个解决方案...

  • 将我的check_box 转换为check_box_tag,替换多选,并添加一些javascript 以在用户单击check_box_tags 时“检查”选择值。然后,参数将直接在控制器中相同。
  • 在控制器中添加一个小代码以“调整”我的参数。

什么解决方案不那么丑?或者还有其他的吗?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-2


    【解决方案1】:

    我找到了一个解决方案,使用我不知道的“多个”选项。

    <% MyModel::AS.each do |a_value| %>
      <%= f.check_box(:a, { :multiple => true }, a_value) %>
    <% end %>
    

    结果参数有点奇怪,但应该可以。

    {"my_model" => { "a" => ["0", "a_value1", "0", "a_value2", "0"] }
    

    从@Viren 编辑:在函数末尾传递nil

      <%= f.check_box(:a, { :multiple => true }, a_value, nil) %>
    

    完美运行。

    【讨论】:

    • 在最后通过nil,它会按预期工作检查this
    • @Viren 谢谢提示。
    • 如果需要,请编辑您的答案,那里还有一个错字。在&lt;% MyModel::AS.each do |a_value| 之后需要%&gt;。只是说
    • 我个人对此的看法:这将是定义用户可能拥有的角色的绝佳方式。这样,角色定义是硬编码的,您不需要任何额外的连接或查询来从数据库中获取其他数据,因为它们都在您的序列化字段中。太棒了!
    【解决方案2】:

    还有一个值得一提的解决方案,如果您有has_and_belongs_to_manyhas_many through 关系,则可以使用collection_check_boxes 表单助手轻松将记录插入数据库。 See documentation here.

    <%= f.collection_check_boxes :mymodel_ids, MyModel::AS, :id, :name do |m| %>
      <%= m.check_box %> <%= m.label %>
    <% end %>
    

    然后,在控制器中我们将允许mymodel_ids 属性:

    params.require(:mymodel).permit(:name, mymodel_ids:[])
    

    我们还可以设置模型验证,要求至少选中一个复选框:

    validates :mymodel_ids, presence: true
    

    此方法的另一个好处是,如果您稍后编辑mymodel 记录并取消选中其中一个复选框,则其记录将从save 上的many_to_many 关联表中删除。

    【讨论】:

    • 这是指南中的任何地方吗?我什么也找不到。能给我链接吗?谢谢!
    • @Metaphysiker,这里是文档链接:edgeapi.rubyonrails.org/classes/ActionView/Helpers/…
    • presence 验证是否应该与此选项一起正常工作?或者由于collection_check_boxes 包含一个空字符串,即使没有选中任何复选框,验证是否通过?
    • @TravisSmith 存在验证肯定有效,因为 Rails 将空字符串视为空白输入,不会认为它存在。
    【解决方案3】:

    你可以这样做:

    <% MyModel::AS.each do |a_value| %>
      <%= f.check_box("a[]", a_value) %>  
    <% end %>
    

    这将使参数如下到达服务器

    { :my_model => { :a => [:a_value1, :a_value2] } }
    

    【讨论】:

      【解决方案4】:

      如果你已经有一个 select_tag

      <%= select_tag "filters", options_from_collection_for_select(filter_values, "id", "name", selected_ids), multiple:true, class:"form-control" %>
      

      并且想用 check_box_tag 替换它,你需要实现这样的东西:

      <div class="checkbox-inline">
          <%= check_box_tag "filters[]", value.id, selected_ids.include?(value.id), { :multiple => true} %>
          <%= value.name %>
      </div>
      

      请注意名称上的结束括号,这需要捕获复选框结果相同的参数。

      当我实现这个时,select_tag和check_box_tag之间的参数格式相同

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-22
        • 2013-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-22
        相关资源
        最近更新 更多