【问题标题】:HABTM checkbox in a nested form嵌套形式的 HABTM 复选框
【发布时间】:2013-02-14 15:51:23
【问题描述】:

我正在尝试以嵌套形式实现 HABTM 复选框。

目前,我有 3 个模型。主题、课程和小组。 关联如下: 每个科目都有很多课。 每节课都有并属于许多组。

现在,我正尝试在一个创建和编辑表单上实现所有这些。 这样一课就嵌套在主题中,并且对于每节课,都有一个组复选框列表来实现 HABTM 关系。

我在实施 HABTM 关系时遇到了麻烦,因为每个科目有很多课程,我不确定如何区分不同的课程。

为了进一步详细说明,我可以让嵌套表单工作,但我无法让 HABTM 复选框保存到正确的课程中。 以下代码示例是我的 HABTM 复选框实现。

  <% Group.all.each do |group|%>
      <%= check_box_tag "subject[lessons_attributes[0]][group_ids][]", group.id, f.object.groups.include?(group) %>
      <%= group.group_index %>
  <%end%>

目前,我已使用“subject[lessons_attributes[0]][group_ids][]”这一行将其保存到第一课。

但是,课程数量各不相同,我不太确定如何确定课程“编号”,即“subject[lessons_attributes[0]][group_ids][ ]”。这样我就可以将小组保存到正确的课程中。

任何建议将不胜感激。

【问题讨论】:

  • 澄清一下,您希望每节课都有一个单独的复选框列表吗?
  • 是的,但是课程嵌套在主题中,我不确定如何获得发送的号码。

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.2 rails-activerecord


【解决方案1】:

对于那些使用 Rails 4 并有同样问题(和我一样)的人

@Viktor Trón 的答案中的Group.all.each 循环是不必要的: 有一个新的 FormBuilder 方法,collection_check_boxes,就是为此而创建的!

您的代码将是:

<% form_for @subject do |form| %>
  ....
  <% @subject.lessons.each_with_index do |l, i| %>
     <%= form.fields_for :lessons, l do |lesson_fields|%>
        <%= lesson_fields.collection_check_boxes :group_ids, Group.all, :id, :group_index %>
     <% end %>
 <% end %>
<% end %>

然后您必须将accepts_nested_attributes_for :lessons 添加到您的Subject 模型中,并在您的SubjectsController 中,将subject_params 方法更改为“允许”课程的嵌套参数:

params.require(:subject).permit(..., lessons_attributes: [:id, group_ids: []])

在您的SubjectsController 中,createupdate 操作保持不变:例如,@subject = Subject.create(subject_params) 将创建主题、相关课程并正确更新它们与组的 HABTM 关系(除非我在某处犯了错误!)。

【讨论】:

    【解决方案2】:

    最佳实践是在主题上预先构建(一些)课程对象(即 form.object),然后遍历它们以获得每个课程的字段。 如果您使用simple_formformtastic,通过复选框选择集合很容易:

    <% form_for @subject do |form| %>
      ....
      <% form.fields_for :lessons do |lesson_form| %>
        ...
        <% lesson_form.input :group_ids, :as => :check_boxes %>
    

    如果您想使用check_box_tag,您应该使用索引遍历课程并将索引替换为您的复选框名称:

    <% form_for @subject do |form| %>
      ....
      <% @subject.lessons.each_with_index do |l, i| %>
         <% Group.all.each do |group|%>
            <%= check_box_tag "subject[lessons_attributes[#{i}]][group_ids][]", group.id, l.groups.include?(group) %>
            <%= group.group_index %>
         <% end %>
    

    【讨论】:

    • 非常感谢,让我试试看。
    • 使用第二种方法并参考this question on implementation for with index. stackoverflow.com/questions/4853373/rails-fields-for-with-index。将来我可能会考虑使用简单的形式。再次感谢!
    • 为什么在复选框名称的末尾加上[]
    • [] 符号向浏览器和 Rails 表明多个同名但值不同的 HTTP 参数将与表单一起提交。数组表示法表示一个值数组将与相同的名称相关联。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    • 1970-01-01
    相关资源
    最近更新 更多