search_helper.rb 2.37 KB
Newer Older
Zac Wood's avatar
Zac Wood committed
1
module SearchHelper
2
  class GenericItem
3
4
5
    attr_reader :data
    attr_reader :type
    
6
7
8
9
10
    def initialize(type, data)
      @type = type
      @data = data
    end
    
11
    def self.fetchall(query_string, sort_mode=:auto)
12
      models = []
13
14
      models += fetch_instructors query_string
      models += fetch_courses query_string
15
16
17
18
19
20
21
22
23
24
      build_list(models)
    end
    
    def self.fetch_instructors(query_string)
      Instructor.from_name(Instructor.select("*"), query_string).all
    end
    
    def self.fetch_courses(query_string)
      query_string.upcase!
      CourseReplacementHelper.replace!(query_string)
25
26
27
28
      base_query = Course.select("courses.*, count(course_sections.id) AS section_count")
                         .left_outer_joins(:course_sections)
                         .having("section_count > 0")
                         .group("courses.id")
29
30
31
32
  
      subj = nil
      query_string.scan(/(?<= |^)([a-zA-Z]{2,4})(?=$| )/).each do |a|
        s = a[0]
33
        if get_count(Course.from_subject(base_query, s)).positive?
34
35
36
37
38
39
40
41
          subj = s
          base_query = Course.from_subject(base_query, subj)
          query_string.remove!(s)
        end
      end
   
      query_string.scan(/(?<= |^)(\d{3})(?=$| )/).each do |a|
        s = a[0]
42
43
        next unless !subj.nil? && get_count(Course.from_course_number(base_query, s)).positive?
        base_query = Course.from_course_number(base_query, s)
44
45
46
        return base_query.all
      end
      
47
48
49
50
51
52
53
54
55
      stripped_query_string = query_string.gsub(/ +/, " ").strip
      
      # There's more to parse
      if stripped_query_string.length.positive?
        base_query = Course.from_title(base_query, stripped_query_string)
                           .order("section_count DESC")
      else
        base_query = base_query.order("courses.course_number ASC")
      end
56
        
57
58
59
60
61
62
63
64
      base_query.all
    end
      
    
    # 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|
65
        list.push(GenericItem.new(model.class.name.underscore.to_sym, model))
66
67
68
69
      end
      
      list
    end
70
71
72
73
74
75
76
77
78
    
    def self.get_count(base_query)
      # I think I finally hit a limit of active record
      ActiveRecord::Base.connection.execute("SELECT COUNT(*) AS count FROM (#{base_query.to_sql})")[0]["count"]
    end
    
    def to_s()
      @type
    end
79
  end
Zac Wood's avatar
Zac Wood committed
80
end