/app/models/search_agent.rb
Ruby | 225 lines | 159 code | 27 blank | 39 comment | 35 complexity | dd9fbeeef22cde743e991cfe2882087a MD5 | raw file
- # SearchAgent is used to search language schools.
- # See SiteSearch for the website search
- class SearchAgent
- MAX_RESULTS = 100 # max number of search results
- attr_reader :per_page, :school_count, :country_id, :city_id, :page_title
- def initialize
- @seed = Time.now.hour # change this seed every hour, so that unpaid results are randomized
- @per_page_default = 5
- @country_id = nil
- @city_id = nil
- end
- # By default, returns the list of matched schools, the school count, and the number of results per page
- def search_schools(params, paginate=true)
- #RubyProf.start
- page = params[:page].blank? ? 1 : params[:page].to_i
- @per_page = params[:per_page] || @per_page_default
- @conditions = ['langCode=1']
- @conditions << 'publicPrivateCode=1' if params[:show_private].blank?
- @conditions << 'schools.deleted=0'
- @order_by = "sortCode ASC, rand(#{@seed})"
- # recommend a page title
- @page_title = 'Spanish Language Schools'
- self.handle_conditions(params)
- limit=nil
- offset=nil
- if paginate
- limit = @per_page
- offset = (page-1)* @per_page
- end
- school_all = School.prioritized.
- includes([:country, :city, :stats]).
- where(@conditions.join(' AND ')).
- limit(limit).offset(offset)
- #schools=school_all[offset..offset+limit]
- schools=school_all
- @school_count = School.count_by_sql("SELECT count(*) FROM schools WHERE #{@conditions.join(' AND ')}")
- #@school_count=school_all.length;
- @school_count = MAX_RESULTS if @school_count > MAX_RESULTS
- #result = RubyProf.stop
- #printer = RubyProf::FlatPrinter.new(result)
- #f = File.new('/tmp/prof.txt', 'w')
- #printer.print(f)
- #f.close
- return schools, @school_count, @per_page if paginate
- return schools if !paginate
- end
- # Method used by the search method. Essentially, code pulled
- # into its own method for improved readability
- def handle_conditions(params)
- if !params[:search].blank?
- @conditions << "schoolName LIKE '%#{params[:search]}%'"
- end
- # city
- if(!params[:relCityID].blank? && params[:relCityID].to_i > 0)
- @city_id = params[:relCityID].to_i
- cityHash = City.lookup(@city_id)
- @country_id = cityHash['relCityID']
- @conditions << "relCityID=#{params[:relCityID]}"
- countryHash = Country.lookup(cityHash['country_id'])
- @page_title += ' in ' + cityHash['enName'] + ', ' + countryHash['enName']
- # country
- elsif(!params[:relCountryID].blank? && params[:relCountryID].to_i > 0)
- @country_id = params[:relCountryID].to_i
- @conditions << "relCountryID=#{params[:relCountryID]}"
- countryHash = Country.lookup(@country_id)
- @page_title += ' in ' + countryHash['enName']
- end
- if !params[:collegeCreditCode].blank?
- handle_param(params[:collegeCreditCode],'collegeCreditCode', 1, ' offering College Credit')
- handle_param(params[:collegeCreditCode],'collegeCreditCode', 2, ' NOT offering College Credit')
- end
- if !params[:liveWithFamilyCode].blank?
- handle_param(params[:liveWithFamilyCode],'liveWithFamilyCode', 1, ' offering Family Accomodations')
- handle_param(params[:liveWithFamilyCode],'liveWithFamilyCode', 2, ' NOT offering Family Accomodations')
- end
- if !params[:privateApartmentCode].blank?
- handle_param(params[:privateApartmentCode],'privateApartmentCode', 1, ' offering Apartments')
- handle_param(params[:privateApartmentCode],'privateApartmentCode', 2, ' NOT offering Apartments')
- end
- if !params[:individualCode].blank?
- handle_param(params[:individualCode],'individualCode', 1, ' offering Private Instruction')
- handle_param(params[:individualCode],'individualCode', 2, ' NOT offering Private Instruction')
- end
- if !params[:classCode].blank?
- handle_param(params[:classCode],'classCode', 1, ' offering Class Instruction')
- handle_param(params[:classCode],'classCode', 2, ' NOT offering Class Instruction')
- end
- if !params[:costCode].blank?
- School.cost_codes.each do |value, message|
- handle_param(params[:costCode],'costCode', value, ' with a weekly cost of ' + School.weekly_cost(value))
- end
- end
- if !params[:schoolSizeCode].blank?
- School.school_size_codes.each do |value, message|
- handle_param(params[:schoolSizeCode],'schoolSizeCode', value, message + ' ', true)
- end
- end
- if !params[:classSizeCode].blank?
- School.class_size_codes.each do |value, message|
- handle_param(params[:classSizeCode],'classSizeCode', value, ' with ' + message)
- end
- end
- # school name match
- # param is qstr
- if !params[:qstr].blank?
- qstr = params[:qstr]
- safe_qstr = qstr.gsub(/'/,"''").gsub(/;/,'').gsub(/from /,'invalid')
- @conditions << "schools.schoolName LIKE '%#{safe_qstr}%'"
- @page_title += " with name matching \"#{qstr}\""
- end
- =begin ## simplifying this because it's 1% of traffic but 30% of CPU
- # for Rails 3, use the activities and programs in a separate query to avoid large join tables
- # special programs and activities
- activities = params[:activities]
- if !activities.blank? && !activities.index(';')
- school_ids = School.select("school_id as id").from("other_program_relations").where("other_program_id=#{activities.to_i}").collect {|s| s.id }
- @conditions << "schools.id IN (#{school_ids.join(", ")})"
- @page_title += ' offering ' + OtherProgram.lookup(activities)['en']
- end
- programs = params[:programs]
- if !programs.blank? && !programs.index(';')
- school_ids = School.select("school_id as id").from("other_program_relations").where("other_program_id=#{programs.to_i}").collect {|s| s.id }
- @conditions << "schools.id IN (#{school_ids.join(", ")})"
- @page_title += ' offering ' + OtherProgram.lookup(programs)['en']
- end
- =end
- if !params[:browse_mode].blank?
- browse_mode = params[:browse_mode].to_i
- # browse_mode = 200 collegeCreditCode 1=Yes 2=No
- if(browse_mode==200)
- @conditions << "collegeCreditCode=1"
- @page_title += " offering College Credit"
- # browse_mode = 210 Family Accomodations liveWithFamilyCode 1=Yes 2=No
- elsif(browse_mode==210)
- @conditions << "liveWithFamilyCode=1"
- @page_title += " offering Family Accomodations"
- elsif(browse_mode==220)
- @conditions << "privateApartmentCode=1"
- @page_title += " offering Apartments"
- elsif(browse_mode==230)
- @conditions << "individualCode=1"
- @page_title += " offering Private Instruction"
- elsif(browse_mode==240)
- @conditions << "classCode=1"
- @page_title += " offering Class Instruction"
- elsif(browse_mode==10)
- @order_by = 'sortCode ASC'
- @page_title += ' sorted by Value'
- elsif(browse_mode==20)
- @order_by = 'qualityCode DESC, sortCode ASC'
- @page_title += ' sorted by Quality'
- elsif(browse_mode==30)
- @order_by = 'costCode ASC, sortCode ASC'
- @page_title += ' sorted by Weekly Cost'
- elsif(browse_mode==35)
- @order_by = 'levelCode DESC, sortCode ASC'
- @page_title += ' sorted by Level of Instruction'
- elsif(browse_mode==40)
- @order_by = 'schoolSizeCode ASC, sortCode ASC'
- @page_title += ' sorted by School Size (small to large)'
- elsif(browse_mode==50)
- @order_by = 'classSizeCode ASC, sortCode ASC'
- @page_title += ' sorted by Class Size (small to large)'
- end
- end
- end
- ####################### PRIVATE METHODS #####################################
- private
- # returns the given value as String or Integer object, even if nil
- # nil Integers will return -1; nil String will return the empty string
- def non_nil(value, klass=String)
- return '' if nil && klass==String
- return -1 if nil && klass==Integer
- return value.to_i if klass==Integer
- return value.to_s if klass=String
- end
- def handle_param(value, db_col, should_equal, title, prepend_title=false)
- return if !value || value.blank?
- begin
- add_conditions=false
- if should_equal.kind_of?(Integer)
- if value.to_i==should_equal
- add_conditions = true
- end
- elsif should_equal.kind_of?(String)
- if value.to_s.eql?(should_equal)
- add_conditions = true
- end
- end
- if add_conditions
- @conditions << db_col + '=' + should_equal.to_s
- @page_title += title if !prepend_title
- @page_title = title + @page_title if prepend_title
- end
- rescue => e
- end
- end
- end