Rails5 - 使用has_many更新连接表:through:using fields_for

时间:2017-08-23 17:51:10

标签: ruby-on-rails

我无法更新我的联接表course_students

当我创建新学生时,我想从下拉列表中选择一门课程(来自课程表中已保存的两门课程Course1Course2)并更新course_students。而且我希望我的couse_students表是这样的。

 id | student_id | course_id |         created_at         |         updated_at         
----+------------+-----------+----------------------------+----------------------------

  1 |          1 |         1 | 2017-08-23 16:41:57.228094 | 2017-08-23 16:41:57.228094

感谢http://railscasts.com/episodes/17-habtm-checkboxes-revised?view=asciicast,我发现以下代码适用于radio_button_tag。但是,当我将wrong number of arguments更改为radio_button_tag时,会出现错误select_tag

此外,我不确定这是否正确,因为信息似乎有点旧。经过一些谷歌搜索后,我经常发现人们在field_for中使用new.html.erb,所以我尝试了但我无法更新course_students表格。

将来,我想在course_students表中添加其他列,例如teacher,date_from,class_room等。

我真的很感谢你的帮助。

·模型

class Student < ApplicationRecord
  has_many :course_students
  has_many :courses, :through => :course_students

  accepts_nested_attributes_for :course_students
end

class Course < ApplicationRecord
  has_many :course_students
  has_many :students, :through => :course_students

end

class CourseStudent < ApplicationRecord
  belongs_to :student
  belongs_to :course

end

·迁移

class CreateStudents < ActiveRecord::Migration[5.1]
  def change
    create_table :students do |t|
      t.string :first_name
      t.string :middle_name
      t.string :last_name

      t.timestamps
    end
  end
end

class CreateCourses < ActiveRecord::Migration[5.1]
  def change
    create_table :courses do |t|
      t.string :name

      t.timestamps
    end
  end
end

class CreateCourseStudents < ActiveRecord::Migration[5.1]
  def change
    create_table :course_students do |t|
      t.integer :student_id
      t.integer :course_id

      t.timestamps
    end
  end
end

·课程表

id |     name     |         created_at         |         updated_at         
----+--------------+----------------------------+----------------------------
 1 | Course1 | 2017-08-22 20:03:46.226893 | 2017-08-22 20:03:46.226893
 2 | Course2    | 2017-08-22 20:03:46.228765 | 2017-08-22 20:03:46.228765

·student.controller,强大的参数。

  def student_params
    params.require(:student).permit(:first_name, :middle_name, :last_name, course_ids: [], date_froms: [] )
  end

·new.html.erb

<h1>Create new student</h1>
<%= form_for(@student) do |f| %>
    <%= f.label :first_name %>
    <%= f.text_field :first_name %>

    <%= f.label :middle_name %>
    <%= f.text_field :middle_name %>

    <%= f.label :last_name %>
    <%= f.text_field :last_name %>

    <%= Course.all.each do |course| %>
        <%= radio_button_tag "student[course_ids][]", course.id, @student.course_ids.include?(course.id), id: dom_id(course)%>
        <%= label_tag dom_id(course), course.name %>
    <% end %>

    <%= f.submit "Create new student", class: "btn btn-primary" %>
<% end %>

2 个答案:

答案 0 :(得分:1)

使用nested_form_for代替form_for,而course_students使用嵌套表单助手提供的field_forhttps://github.com/ryanb/nested_form

<h1>Create new student</h1>

<%= nested_form_for(@student) do |f| %>
  <%= f.label :first_name %>
  <%= f.text_field :first_name %>

  <%= f.label :middle_name %>
  <%= f.text_field :middle_name %>

  <%= f.label :last_name %>
  <%= f.text_field :last_name %>

  <%= f.fields_for :course_students do |ff| %>
   <%= ff.hidden_field :student_id, value: @student.id %>
   <%= ff.collection_select :course_id, Course.all, :id, :name %>
  <% end %>

  <%= f.submit "Create new student", class: "btn btn-primary" %>
<% end %>

你需要允许在控制器中使用course_students params:

def student_params
  params.require(:student).permit(:first_name, :middle_name, :last_name, course_students_attributes: [ :course_id, :student_id] )
end

答案 1 :(得分:0)

发现以下代码有效!

students_controller

  def new
    @student = Student.new
    @student.course_students.build
  end

  private

  def student_params
    params.require(:student).permit(:first_name, :middle_name, :last_name, course_students_attributes: [ :course_id, :student_id] )
  end

new.html.erb

<%= f.fields_for :course_students do |ff| %>
  <%= ff.hidden_field :student_id, value: @student.id %>
  <%= ff.collection_select :course_id, Course.all, :id, :name %>
<% end %>

谢谢!