course_section.rb 2.32 KB
Newer Older
1 2
# Contains logic belonging to the +CourseSection+ model.
class CourseSection < ApplicationRecord
3
  # Each +CourseSection+ belongs to a +Course+ and an +Instructor+.
Zac Wood's avatar
Zac Wood committed
4
  belongs_to :course
5
  belongs_to :instructor
Zac Wood's avatar
Zac Wood committed
6 7 8 9 10

  # Ensure all necessary fields are present.
  validates :name, presence: true
  validates :crn, presence: true
  validates :title, presence: true
11
  validates :course_id, presence: true
12

13 14 15 16
  def is_lecture?
    section_type == "Lecture"
  end

Zac Wood's avatar
Zac Wood committed
17
  def labs
18
    return nil unless is_lecture?
Zac Wood's avatar
Zac Wood committed
19

20 21 22 23
    # Lectures have names formatted like "MATH 214 001"
    # Labs/recitations have the title format "Recitation for Lecture 001"
    # so, match all the sections in the same course which have the same number
    # as the last element of their titles
Zac Wood's avatar
Zac Wood committed
24
    lecture_number = name.split[name.split.length - 1]
25
    labs_for_section = course.course_sections.select do |s|
Zac Wood's avatar
Zac Wood committed
26
      s.title.split[s.title.split.length - 1] == lecture_number
Zac Wood's avatar
Zac Wood committed
27
    end
28 29 30 31 32 33 34 35 36 37 38

    labs_for_section.map do |lab|
      [self, lab]
    end
  end

  def overlaps?(other)
    t1_start, t1_end = Time.parse(start_time), Time.parse(end_time)
    t2_start, t2_end = Time.parse(other.start_time), Time.parse(other.end_time)

    (t1_start <= t2_end && t2_start <= t1_end) && Set.new(days.split).intersect?(Set.new(other.days.split))
Zac Wood's avatar
Zac Wood committed
39 40
  end

41 42 43 44
  # Select all course sections that have an instructor that matches the given name
  def self.with_instructor(name: "")
    joins(:instructor).where("instructors.name LIKE ?", "%#{name}%").select('course_sections.*, instructors.name as instructor_name')
  end
Zach Perkins's avatar
Zach Perkins committed
45

46
  def self.from_crn(base_query, crn)
Zach Perkins's avatar
Zach Perkins committed
47
    base_query.where("course_sections.crn = ?", crn)
48
  end
Zach Perkins's avatar
Zach Perkins committed
49

50
  def self.from_course_id(base_query, course_id)
Zach Perkins's avatar
Zach Perkins committed
51
    base_query.where("course_sections.course_id = ?", course_id)
52
  end
Zach Perkins's avatar
Zach Perkins committed
53

54 55
  # Select all revelevant course sections given the provided filters
  def self.fetch(filters)
56
    query = CourseSection.joins(:course).select("course_sections.*")
Zach Perkins's avatar
Zach Perkins committed
57

58 59 60 61 62 63
    filters.each do |filter, value|
      case filter
      when "crn"
        query = from_crn(query, value)
      when "course_id"
        query = from_course_id(query, value)
64 65
      when "course_number"
        query = Course.from_course_number(query, value)
66 67
      when "subject"
        query = Course.from_subject(query, value)
68 69
      when "title"
        query = Course.from_title(query, value)
70 71
      end
    end
Zach Perkins's avatar
Zach Perkins committed
72

73
    query
74
  end
Zac Wood's avatar
Zac Wood committed
75
end