course.rb 1.9 KB
Newer Older
Zac Wood's avatar
Zac Wood committed
1
2
3
# Contains logic regarding the +Course+ model.
#
# TODO: Add more docs
4

Zac Wood's avatar
Zac Wood committed
5
class Course < ApplicationRecord
Zac Wood's avatar
Zac Wood committed
6
  # Each course belongs to a +Semester+
Zac Wood's avatar
Zac Wood committed
7
  belongs_to :semester
8
  has_many :course_sections
Zac Wood's avatar
Zac Wood committed
9

10
  # Ensure all necessary are fields present.
Zac Wood's avatar
Zac Wood committed
11
12
13
14
  validates :course_number, presence: true
  validates :subject, presence: true
  validates :semester_id, presence: true

Zac Wood's avatar
Zac Wood committed
15
16
17
18
  def full_name
    "#{subject} #{course_number}"
  end
  
19
20
21
  def self.from_subject(base_query, subject)
    base_query.where("courses.subject = ?", subject.upcase)
  end
Zach Perkins's avatar
Zach Perkins committed
22

23
  def self.from_course_number(base_query, course_number)
Zach Perkins's avatar
Zach Perkins committed
24
    base_query.where("courses.course_number = ?", course_number)
Zach Perkins's avatar
Zach Perkins committed
25
  end
Zach Perkins's avatar
Zach Perkins committed
26

Zach Perkins's avatar
Zach Perkins committed
27
  def self.from_title(base_query, title)
28
    puts title
Zach Perkins's avatar
Zach Perkins committed
29
    # Temporary really disgusting regex that I hate with all my heart
30
    title = (title + " ").upcase.gsub(/(I+) +/, '\1$').gsub(/ +/, "% ").tr('$', ' ')
31
    base_query.where("UPPER(courses.title) LIKE UPPER(?) or UPPER(courses.title) LIKE UPPER(?)", "%#{title.strip}", "%#{title}%")
32
  end
Zach Perkins's avatar
Zach Perkins committed
33

Zach Perkins's avatar
Zach Perkins committed
34
35
36
  # Given a list of filters, collect a list of matching elements. This makes it
  # so you can just pass the arguments straight thru
  def self.fetch(filters)
37
    # join with course_sections so that we can get a section count for each course and then sort by that
38
39
40
41
    query = Course.left_outer_joins(:course_sections)
                  .select("courses.*, COUNT(course_sections.id) AS section_count")
                  .group("courses.id")
                  .order("section_count DESC")
42
43

    filters.each do |filter, value|
Zach Perkins's avatar
Zach Perkins committed
44
45
46
47
48
49
50
      case filter
      when "subject"
        query = from_subject(query, value)
      when "course_number"
        query = from_course_number(query, value)
      when "title"
        query = from_title(query, value)
51
52
      when "instructor"
        query = Instructor.from_name(query.joins("INNER JOIN instructors ON course_sections.instructor_id = instructors.id"), value)
Zach Perkins's avatar
Zach Perkins committed
53
54
      end
    end
Zach Perkins's avatar
Zach Perkins committed
55

56
    query
Zach Perkins's avatar
Zach Perkins committed
57
  end
Zac Wood's avatar
Zac Wood committed
58
end