嵌套表单中的HABTM复选框

But*_*eer 5 ruby ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2 rails-activerecord

我试图以嵌套的形式实现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%>
Run Code Online (Sandbox Code Playgroud)

目前,我已使用此行"subject [lessons_attributes [0]] [group_ids] []"将其保存到第一课.

但是,课程数量各不相同,我不太确定如何确定课程"数字",即"subject [lessons_attributes [ 0 ]] [group_ids] []"中的粗体0 .这样我就可以将小组保存到正确的课程中.

任何意见,将不胜感激.

Oli*_*nce 9

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

@ViktorTró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 %>
Run Code Online (Sandbox Code Playgroud)

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

params.require(:subject).permit(..., lessons_attributes: [:id, group_ids: []])
Run Code Online (Sandbox Code Playgroud)

在你的SubjectsController,create或者update动作保持不变:@subject = Subject.create(subject_params)例如,将创建主题,相关的课程并正确地将他们的HABTM关系更新到组(除非我在某处犯了错误!).


Vik*_*rón 5

最佳实践是预先构建(一些)主题上的课程对象(即form.object),然后迭代它们以获得每课程字段.如果你使用simple_formformtastic,收集通过复选框选择很简单:

<% form_for @subject do |form| %>
  ....
  <% form.fields_for :lessons do |lesson_form| %>
    ...
    <% lesson_form.input :group_ids, :as => :check_boxes %>
Run Code Online (Sandbox Code Playgroud)

如果您想使用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 %>
Run Code Online (Sandbox Code Playgroud)