To Examples

School2 Example

Directions

  1. Create a new Rails project named School2.
  2. Generate a Rails scaffold named Student with these fields.
    Field Datatype
    name string
    gender string
    phone string
  3. Generate a Rails scaffold named Course with these fields.
    Field Datatype
    course_num string
    title string
    credit_hours integer
  4. From the Command Prompt Window, generate a migration to create the join table named courses_students. (Note that courses and students are in alphabetic order.)
    > rails g migration CreateCoursesStudents course_id:integer student_id:integer
    
    Run rake db:migrate to create the table.
  5. Source code for the School2 seed file School/db/seeds2.rb.
  6. Add this line to the Course model file School2/app/models/course.rb:
    has_and_belongs_to_many :students
    
  7. Add this line to the Student model file School2/app/models/student.rb:
    has_and_belongs_to_many :courses
    
  8. At the bottom of the Course and Student index views, add a link to the index view of the other model.
  9. View the show pages with these URLs:
    http://localhost:3000/students
    http://localhost:3000/courses
    
  10. Modify the Student show view to show the courses in which the student is enrolled (same as School1 Example):
    <h3>Courses for <%= @student.name %></h3>
    
    <table>
      <tr>
        <th>Course Number</th>
        <th>Course Title</th>
        <th>Credit Hours</th>
      </tr>
    
      <% @student.courses.each do |c| %>
      <tr>
        <td><%= c.course_num %></td>
        <td><%= c.title %></td>
        <td><%= c.credit_hours %></td>
      </tr>
      <% end %>
    </table>
    
  11. Modify the Course show view to show the students that are enrolled in the course (same as School1 Example):
    <h3>Students in <%= @course.course_num %></h3>
    
    <table>
      <tr>
        <th>Name</th>
        <th>Gender</th>
        <th>Phone Number</th>
      </tr>
    
      <% @course.students.each do |s| %>
      <tr>
        <td><%= s.name %></td>
        <td><%= s.gender %></td>
        <td><%= s.phone %></td>
      </tr>
      <% end %>
    </table>
    
  12. Add a column to the Course index view to show the number of students in each course (same as School1 Example):
     <td><%= course.students.count %></td>
    

We now add the capability of enrolling students in new courses.

  1. Add these methods to the Student model: enrolled_in?, unenrolled_courses
    # Check if student is enrolled in a course
    def enrolled_in?(course)
      return self.courses.include?(course) 
    end
    
    # Get list of all courses that a 
    # student is not enrolled
    def unenrolled_courses
      return Course.all - self.courses
    end
  2. Add this method to the students controller: add_course:
    def add_course
      @student = Student.find(params[:id])
      @course = Course.find(params[:course])
    
      if not @student.enrolled_in?(@course)
        # << is an ActiveRecord operator that adds
        # a row to the courses_students join table.
        @student.courses << @course
      end
      redirect_to @student
    end
    
  3. Add this form to the bottom of the Student show method before the Edit and Back links.
    <% if @student.courses.count < Course.count %>
      <p>Enroll in a course.</p>
      <%= form_tag add_course_student_path(@student) do %>
        <%= select_tag(:course,
            options_from_collection_for_select(
              @student.unenrolled_courses, :id, :course_num)) %>
        <%= submit_tag 'Enroll' %>
      <% end %>
    <% end %>
    
  4. Add a route for the add_course method in School2/config/routes.rb. Replace the route resources :students to
     resources :students do
      member do
        post :add_course
      end
    end