search_helper.rb 3.42 KB
Newer Older
Zac Wood's avatar
Zac Wood committed
1
module SearchHelper
2 3 4 5
  def in_cart?(crn)
    @cart.include? crn.to_s
  end

6 7 8 9
  class GenericQueryData
    attr_reader :semester
    attr_reader :sort_mode
    attr_reader :search_string
10

11 12 13 14 15 16
    def initialize(search_string, sort_mode, semester)
      @semester = semester
      @sort_mode = sort_mode
      @search_string = search_string
    end
  end
17

18
  class GenericItem
19 20
    attr_reader :data
    attr_reader :type
21

22 23 24 25
    def initialize(type, data)
      @type = type
      @data = data
    end
26

Zach Perkins's avatar
Zach Perkins committed
27
    def self.fetchall(search_string, sort_mode: :auto, semester: :fall2018)
28
      query_data = GenericQueryData.new(search_string, sort_mode, semester)
29
      models = []
30 31
      models += fetch_instructors(query_data)
      models += fetch_courses(query_data)
32 33
      build_list(models)
    end
34

35
    def self.fetch_instructors(query_data)
36 37
      Instructor.from_name(Instructor.select("instructors.*, COUNT(courses.id) AS section_count").from("course_sections"), query_data.search_string)
                .joins("LEFT OUTER JOIN instructors ON instructors.id = course_sections.instructor_id")
38
                .joins("LEFT OUTER JOIN courses ON courses.id = course_sections.course_id AND course_sections.semester_id = #{query_data.semester.id}")
39
                .group("instructors.id").all
40
    end
41

42 43
    def self.fetch_courses(query_data)
      query_string = query_data.search_string
44 45
      query_string.upcase!
      CourseReplacementHelper.replace!(query_string)
46 47
      base_query = Course.select("courses.*, count(course_sections.id) AS section_count")
                         .left_outer_joins(:course_sections)
Zac Wood's avatar
Zac Wood committed
48
                         .having("count(course_sections.id) > 0")
49
                         .where("course_sections.semester_id = ?", query_data.semester)
50
                         .group("courses.id")
51

52 53 54
      subj = nil
      query_string.scan(/(?<= |^)([a-zA-Z]{2,4})(?=$| )/).each do |a|
        s = a[0]
55
        next unless get_count(Course.from_subject(base_query, s)).positive?
Zac Wood's avatar
Zac Wood committed
56
        # next unless Course.from_subject(base_query, s).count.positive?
57 58 59
        subj = s
        base_query = Course.from_subject(base_query, subj)
        query_string.remove!(s)
60
      end
61

62 63
      query_string.scan(/(?<= |^)(\d{3})(?=$| )/).each do |a|
        s = a[0]
64
        next unless !subj.nil? && get_count(Course.from_course_number(base_query, s)).positive?
Zac Wood's avatar
Zac Wood committed
65
        # next unless !subj.nil? && Course.from_course_number(base_query, s).count.positive?
66
        base_query = Course.from_course_number(base_query, s)
67 68
        return base_query.all
      end
69

70
      stripped_query_string = query_string.gsub(/ +/, " ").strip
71

72
      # There's more to parse
73 74
      base_query = if stripped_query_string.length.positive?
                     Course.from_title(base_query, stripped_query_string)
75
                           .order("section_count DESC")
76 77 78 79
                   else
                     base_query.order("courses.course_number ASC")
                   end

80 81
      base_query.all
    end
82

83 84 85 86
    # Given a set of models, create a list of GenericItems for each model's data
    def self.build_list(models)
      list = []
      models.each do |model|
87
        list.push(GenericItem.new(model.class.name.underscore.to_sym, model))
88
      end
89

90 91
      list
    end
92

93 94
    def self.get_count(base_query)
      # I think I finally hit a limit of active record
Zac Wood's avatar
Zac Wood committed
95
      ActiveRecord::Base.connection.execute("SELECT COUNT(*) AS count FROM (#{base_query.to_sql}) as q")[0]["count"]
96
    end
97 98

    def to_s
99 100
      @type
    end
101
  end
Zac Wood's avatar
Zac Wood committed
102
end