Reputation: 773
I have a trouble to update my join table course_students
.
When I create a new student, I want to select a course from dropdown list(from two courses Course1
and Course2
which already saved in course table) and update course_students
. And I want my couse_students table to be something like this.
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
Thanks to http://railscasts.com/episodes/17-habtm-checkboxes-revised?view=asciicast, I somehow found out the following code works for radio_button_tag
. But there is an error wrong number of arguments
when I change radio_button_tag
to select_tag
.
Also, I am not sure if this is the correct way because the information seems bit old. After some google search, I often found that people use field_for
in new.html.erb
, so I tried but I could not update course_students
table.
In the future, I would like to add other columns like teacher, date_from, class_room, and something like that in course_students table.
I would really appreciate your help.
・models
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
・migrations
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
・course table
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, strong params.
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 %>
Upvotes: 2
Views: 577
Reputation: 180
Use nested_form_for
instead of form_for
and for course_students use field_for
that nested form helper provide. 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 %>
you needs to permit course_students params in controller like this:
def student_params
params.require(:student).permit(:first_name, :middle_name, :last_name, course_students_attributes: [ :course_id, :student_id] )
end
Upvotes: 1
Reputation: 773
Found out that the following code worked!
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 %>
Thanks!
Upvotes: 0