course.rb 1.88 KB
Newer Older
Zac Wood's avatar
Zac Wood committed
1
# Contains logic regarding the +Course+ model.
Zac Wood's avatar
Zac Wood committed
2
class Course < ApplicationRecord
Zac Wood's avatar
Zac Wood committed
3
  # Each course belongs to a +Semester+
Zac Wood's avatar
Zac Wood committed
4
  belongs_to :semester
5
  has_many :course_sections
Zac Wood's avatar
Zac Wood committed
6

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

Zac Wood's avatar
Zac Wood committed
12
13
14
  def full_name
    "#{subject} #{course_number}"
  end
Zac Wood's avatar
Zac Wood committed
15

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

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

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

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

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

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