Skip to content

Instantly share code, notes, and snippets.

@arelenglish
Last active May 3, 2016 18:22
Show Gist options
  • Save arelenglish/6110438 to your computer and use it in GitHub Desktop.
Save arelenglish/6110438 to your computer and use it in GitHub Desktop.
An simple Gist showing how to add students to courses through an enrollments table with a collection select.

To generate this project, do the following on the command line:

rails generate scaffold student name:string

rails generate scaffold course name:string

rails generate model enrollment student_id:integer course_id:integer

rake db:migrate

Feel free to submit a pull request, or ask any questions!

class Course < ActiveRecord::Base
attr_accessible :name, :student_ids #student_ids is from the collection_select in the view file below
has_many :enrollments
has_many :students, through: :enrollments
# A course may have many students through the join table called enrollments.
end
class CoursesController < ApplicationController
# For simplicity, I left out all the other actions in the controller that are generated by rails because you don't need to edit them fro this.
# I left out: index, show, new, edit, create, destroy
# PUT /courses/1
# PUT /courses/1.json
def update
@course = Course.find(params[:id])
### Added code ###
student_id = params[:course].delete(:students)
if student_id # This if statement makes sure a registration isn't created every time the a course is updated.
registration = Registration.create(:student_id => student_id, :course_id => @course.id) #actual creation of the registration
end
### End added code ###
respond_to do |format|
if @course.update_attributes(params[:course])
format.html { redirect_to @course, notice: 'Course was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @course.errors, status: :unprocessable_entity }
end
end
end
end
class Enrollment < ActiveRecord::Base
attr_accessible :student_id, :course_id
belongs_to :student
belongs_to :course
end
# In app/views/courses
<p>
<b>Name:</b>
<%= @course.name %>
</p>
<!-- The below code just shows which students are enrolled. Since you are pulling from a join table, you have to query the
database to find the name of the student from his id -->
<p>
<b>Enrolled Students</b><br>
<% @course.enrollments.each do |enrollment| %>
<%= Student.find(enrollment.student_id).name %><br>
<% end %>
</p>
<b> Add a student to this course </b>
<%= form_for(@course) do |f| %>
<%= f.collection_select 'student_ids', Student.all, :id, :name, { include_blank: "" } %>
<%= f.submit %>
<% end %>
<!--
collection_select creates a dropdown menu
student_ids is the field in the table that selection will be written to. Note that it's plural because you can add multiple courses
Student.all lists all the students from the students table in the drop down
:id is the actual value from the students table that will be recorded in the student_id field in the registrations table
:name is what users will see as their option to select in the dropdown
{ include_blank: "" } just puts a blank space as the default in the drop down
-->
<!-- In app/views/students -->
<!-- Note, the actual name of the file is show.html.erb. Gist won't let me have two files with the same name -->
<p>
<b>Name:</b>
<%= @student.name %>
</p>
<!-- The below code just shows which courses the student is enrolled in. Since you are pulling from a join table, you have to query the
database to find the name of the course from its id -->
<p>
<b>Courses enrolled in</b><br>
<% @student.enrollments.each do |enrollment| %>
<%= Course.find(enrollment.course_id).name %><br>
<% end %>
</p>
<b> Add this student to a course </b>
<%= form_for(@student) do |f| %>
<%= f.collection_select 'course_ids', Course.all, :id, :name, { include_blank: "" } %>
<%= f.submit %>
<% end %>
<!--
collection_select creates a dropdown menu
course_ids is the field in the table that selection will be written to. Note that it's plural because you can add multiple students
Course.all lists all the courses from the courses table in the drop down
:id is the actual value from the courses table that will be recorded in the course_id field in the registrations table
:name is what users will see as their option to select in the dropdown
{ include_blank: "" } just puts a blank space as the default in the drop down
-->
class Student < ActiveRecord::Base
attr_accessible :name, :course_ids #course_ids is from the_collection select in the view file below
has_many :enrollments #Join table
has_many :courses, through: :enrollments
# A student can be enrolled in many classes through the join table called enrolments
end
class StudentsController < ApplicationController
# Again, for simplicity, I left out all the other actions in the controller that are generated by rails because you don't need to edit them fro this.
# I left out: index, show, new, edit, create, destroy
# PUT /students/1
# PUT /students/1.json
def update
@student = Student.find(params[:id])
### Added code ###
course_id = params[:student].delete(:courses)
if course_id # This makes sure a registration isn't created every time the a student is updated.
registration = Registration.create(:course_id => course_id, :student_id => @student.id)
end
### End added code ###
respond_to do |format|
if @student.update_attributes(params[:student])
format.html { redirect_to @student, notice: 'Student was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @student.errors, status: :unprocessable_entity }
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment