course.rb 1.85 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

15
16
17
  def self.from_subject(base_query, subject)
    base_query.where("courses.subject = ?", subject.upcase)
  end
Zach Perkins's avatar
Zach Perkins committed
18

19
  def self.from_course_number(base_query, course_number)
Zach Perkins's avatar
Zach Perkins committed
20
    base_query.where("courses.course_number = ?", course_number)
Zach Perkins's avatar
Zach Perkins committed
21
  end
Zach Perkins's avatar
Zach Perkins committed
22

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

Zach Perkins's avatar
Zach Perkins committed
30
31
32
  # 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)
33
    # join with course_sections so that we can get a section count for each course and then sort by that
34
35
36
37
    query = Course.left_outer_joins(:course_sections)
                  .select("courses.*, COUNT(course_sections.id) AS section_count")
                  .group("courses.id")
                  .order("section_count DESC")
38
39

    filters.each do |filter, value|
Zach Perkins's avatar
Zach Perkins committed
40
41
42
43
44
45
46
      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)
47
48
      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
49
50
      end
    end
Zach Perkins's avatar
Zach Perkins committed
51

52
    query
Zach Perkins's avatar
Zach Perkins committed
53
  end
Zac Wood's avatar
Zac Wood committed
54
end