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



我在更新连接表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.但是当我radio_button_tag更改为select_tagwrong number of arguments错误。

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

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

我真的很感激你的帮助。

・型号

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

・学生控制器,强大的参数。

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

・新.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 %>

使用nested_form_for而不是form_forcourse_students 使用嵌套表单帮助程序提供的field_for。 https://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参数,如下所示:

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

发现以下代码有效!

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

新.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 %>

谢谢!

相关内容

最新更新