course_section.rb 2.33 KB
Newer Older
Zac Wood's avatar
Zac Wood committed
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

  # Each course belongs to a +Semester+
8
  belongs_to :semester
Zac Wood's avatar
Zac Wood committed
9
10
11
12
13

  # Ensure all necessary fields are present.
  validates :name, presence: true
  validates :crn, presence: true
  validates :title, presence: true
14
  validates :course_id, presence: true
15
  validates :semester_id, presence: true
16

Zac Wood's avatar
Zac Wood committed
17
18
  serialize :rating_questions, Array

Zac Wood's avatar
Zac Wood committed
19
20
  scope :in_semester, ->(semester) { where(semester: semester) }

Zac Wood's avatar
Zac Wood committed
21
22
23
24
  def teaching_rating
    if rating_questions.empty?
      nil
    else
Zac Wood's avatar
Zac Wood committed
25
      "#{rating_questions[0]['instr_mean']} / #{rating_questions[0]['resp']} responses"
Zac Wood's avatar
Zac Wood committed
26
27
28
29
30
31
32
    end
  end

  def course_rating
    if rating_questions.empty?
      nil
    else
Zac Wood's avatar
Zac Wood committed
33
      "#{rating_questions[1]['instr_mean']} / #{rating_questions[1]['resp']} responses"
Zac Wood's avatar
Zac Wood committed
34
35
36
    end
  end

37
38
39
40
41
  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
42
43
  end

44
  def self.latest_by_crn(crn)
45
    where(crn: crn).min_by { |s| s.semester.id }
46
47
  end

48
49
  # Select all course sections that have an instructor that matches the given name
  def self.with_instructor(name: "")
Zac Wood's avatar
Zac Wood committed
50
51
52
    joins(:instructor)
      .where("instructors.name LIKE ?", "%#{name}%")
      .select('course_sections.*, instructors.name as instructor_name')
53
  end
Zach Perkins's avatar
Zach Perkins committed
54

55
  def self.from_crn(base_query, crn)
Zac Wood's avatar
Zac Wood committed
56
    base_query.where(crn: crn)
57
  end
Zach Perkins's avatar
Zach Perkins committed
58

59
  def self.from_course_id(base_query, course_id)
Zac Wood's avatar
Zac Wood committed
60
    base_query.where(course_id: course_id)
61
  end
Zach Perkins's avatar
Zach Perkins committed
62

63
64
  # Select all revelevant course sections given the provided filters
  def self.fetch(filters)
65
    query = CourseSection.joins(:course).select("course_sections.*")
Zach Perkins's avatar
Zach Perkins committed
66

67
68
69
70
71
72
    filters.each do |filter, value|
      case filter
      when "crn"
        query = from_crn(query, value)
      when "course_id"
        query = from_course_id(query, value)
Zach Perkins's avatar
Zach Perkins committed
73
74
      when "course_number"
        query = Course.from_course_number(query, value)
75
76
      when "subject"
        query = Course.from_subject(query, value)
Zach Perkins's avatar
Zach Perkins committed
77
78
      when "title"
        query = Course.from_title(query, value)
79
80
      end
    end
Zach Perkins's avatar
Zach Perkins committed
81

82
    query
83
  end
Zac Wood's avatar
Zac Wood committed
84
end