course.rb 1.93 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
3
  has_many :course_sections
Zac Wood's avatar
Zac Wood committed
4

5
  # Ensure all necessary are fields present.
Zac Wood's avatar
Zac Wood committed
6
7
8
  validates :course_number, presence: true
  validates :subject, presence: true

Zac Wood's avatar
Zac Wood committed
9
10
11
  def full_name
    "#{subject} #{course_number}"
  end
Zac Wood's avatar
Zac Wood committed
12

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

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

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

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

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

50
    query
Zach Perkins's avatar
Zach Perkins committed
51
  end
Zac Wood's avatar
Zac Wood committed
52
53
54
55
56
57
58
59
60

  # build_set builds
  def self.build_set(sections)
    courses = [].to_set
    sections.each do |s|
      courses.add s.course
    end
    courses
  end
Zac Wood's avatar
Zac Wood committed
61
end