PageRenderTime 42ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/app/models/search_agent.rb

https://bitbucket.org/kapilnakhwa/demo-teachme
Ruby | 225 lines | 159 code | 27 blank | 39 comment | 35 complexity | dd9fbeeef22cde743e991cfe2882087a MD5 | raw file
  1. # SearchAgent is used to search language schools.
  2. # See SiteSearch for the website search
  3. class SearchAgent
  4. MAX_RESULTS = 100 # max number of search results
  5. attr_reader :per_page, :school_count, :country_id, :city_id, :page_title
  6. def initialize
  7. @seed = Time.now.hour # change this seed every hour, so that unpaid results are randomized
  8. @per_page_default = 5
  9. @country_id = nil
  10. @city_id = nil
  11. end
  12. # By default, returns the list of matched schools, the school count, and the number of results per page
  13. def search_schools(params, paginate=true)
  14. #RubyProf.start
  15. page = params[:page].blank? ? 1 : params[:page].to_i
  16. @per_page = params[:per_page] || @per_page_default
  17. @conditions = ['langCode=1']
  18. @conditions << 'publicPrivateCode=1' if params[:show_private].blank?
  19. @conditions << 'schools.deleted=0'
  20. @order_by = "sortCode ASC, rand(#{@seed})"
  21. # recommend a page title
  22. @page_title = 'Spanish Language Schools'
  23. self.handle_conditions(params)
  24. limit=nil
  25. offset=nil
  26. if paginate
  27. limit = @per_page
  28. offset = (page-1)* @per_page
  29. end
  30. school_all = School.prioritized.
  31. includes([:country, :city, :stats]).
  32. where(@conditions.join(' AND ')).
  33. limit(limit).offset(offset)
  34. #schools=school_all[offset..offset+limit]
  35. schools=school_all
  36. @school_count = School.count_by_sql("SELECT count(*) FROM schools WHERE #{@conditions.join(' AND ')}")
  37. #@school_count=school_all.length;
  38. @school_count = MAX_RESULTS if @school_count > MAX_RESULTS
  39. #result = RubyProf.stop
  40. #printer = RubyProf::FlatPrinter.new(result)
  41. #f = File.new('/tmp/prof.txt', 'w')
  42. #printer.print(f)
  43. #f.close
  44. return schools, @school_count, @per_page if paginate
  45. return schools if !paginate
  46. end
  47. # Method used by the search method. Essentially, code pulled
  48. # into its own method for improved readability
  49. def handle_conditions(params)
  50. if !params[:search].blank?
  51. @conditions << "schoolName LIKE '%#{params[:search]}%'"
  52. end
  53. # city
  54. if(!params[:relCityID].blank? && params[:relCityID].to_i > 0)
  55. @city_id = params[:relCityID].to_i
  56. cityHash = City.lookup(@city_id)
  57. @country_id = cityHash['relCityID']
  58. @conditions << "relCityID=#{params[:relCityID]}"
  59. countryHash = Country.lookup(cityHash['country_id'])
  60. @page_title += ' in ' + cityHash['enName'] + ', ' + countryHash['enName']
  61. # country
  62. elsif(!params[:relCountryID].blank? && params[:relCountryID].to_i > 0)
  63. @country_id = params[:relCountryID].to_i
  64. @conditions << "relCountryID=#{params[:relCountryID]}"
  65. countryHash = Country.lookup(@country_id)
  66. @page_title += ' in ' + countryHash['enName']
  67. end
  68. if !params[:collegeCreditCode].blank?
  69. handle_param(params[:collegeCreditCode],'collegeCreditCode', 1, ' offering College Credit')
  70. handle_param(params[:collegeCreditCode],'collegeCreditCode', 2, ' NOT offering College Credit')
  71. end
  72. if !params[:liveWithFamilyCode].blank?
  73. handle_param(params[:liveWithFamilyCode],'liveWithFamilyCode', 1, ' offering Family Accomodations')
  74. handle_param(params[:liveWithFamilyCode],'liveWithFamilyCode', 2, ' NOT offering Family Accomodations')
  75. end
  76. if !params[:privateApartmentCode].blank?
  77. handle_param(params[:privateApartmentCode],'privateApartmentCode', 1, ' offering Apartments')
  78. handle_param(params[:privateApartmentCode],'privateApartmentCode', 2, ' NOT offering Apartments')
  79. end
  80. if !params[:individualCode].blank?
  81. handle_param(params[:individualCode],'individualCode', 1, ' offering Private Instruction')
  82. handle_param(params[:individualCode],'individualCode', 2, ' NOT offering Private Instruction')
  83. end
  84. if !params[:classCode].blank?
  85. handle_param(params[:classCode],'classCode', 1, ' offering Class Instruction')
  86. handle_param(params[:classCode],'classCode', 2, ' NOT offering Class Instruction')
  87. end
  88. if !params[:costCode].blank?
  89. School.cost_codes.each do |value, message|
  90. handle_param(params[:costCode],'costCode', value, ' with a weekly cost of ' + School.weekly_cost(value))
  91. end
  92. end
  93. if !params[:schoolSizeCode].blank?
  94. School.school_size_codes.each do |value, message|
  95. handle_param(params[:schoolSizeCode],'schoolSizeCode', value, message + ' ', true)
  96. end
  97. end
  98. if !params[:classSizeCode].blank?
  99. School.class_size_codes.each do |value, message|
  100. handle_param(params[:classSizeCode],'classSizeCode', value, ' with ' + message)
  101. end
  102. end
  103. # school name match
  104. # param is qstr
  105. if !params[:qstr].blank?
  106. qstr = params[:qstr]
  107. safe_qstr = qstr.gsub(/'/,"''").gsub(/;/,'').gsub(/from /,'invalid')
  108. @conditions << "schools.schoolName LIKE '%#{safe_qstr}%'"
  109. @page_title += " with name matching \"#{qstr}\""
  110. end
  111. =begin ## simplifying this because it's 1% of traffic but 30% of CPU
  112. # for Rails 3, use the activities and programs in a separate query to avoid large join tables
  113. # special programs and activities
  114. activities = params[:activities]
  115. if !activities.blank? && !activities.index(';')
  116. school_ids = School.select("school_id as id").from("other_program_relations").where("other_program_id=#{activities.to_i}").collect {|s| s.id }
  117. @conditions << "schools.id IN (#{school_ids.join(", ")})"
  118. @page_title += ' offering ' + OtherProgram.lookup(activities)['en']
  119. end
  120. programs = params[:programs]
  121. if !programs.blank? && !programs.index(';')
  122. school_ids = School.select("school_id as id").from("other_program_relations").where("other_program_id=#{programs.to_i}").collect {|s| s.id }
  123. @conditions << "schools.id IN (#{school_ids.join(", ")})"
  124. @page_title += ' offering ' + OtherProgram.lookup(programs)['en']
  125. end
  126. =end
  127. if !params[:browse_mode].blank?
  128. browse_mode = params[:browse_mode].to_i
  129. # browse_mode = 200 collegeCreditCode 1=Yes 2=No
  130. if(browse_mode==200)
  131. @conditions << "collegeCreditCode=1"
  132. @page_title += " offering College Credit"
  133. # browse_mode = 210 Family Accomodations liveWithFamilyCode 1=Yes 2=No
  134. elsif(browse_mode==210)
  135. @conditions << "liveWithFamilyCode=1"
  136. @page_title += " offering Family Accomodations"
  137. elsif(browse_mode==220)
  138. @conditions << "privateApartmentCode=1"
  139. @page_title += " offering Apartments"
  140. elsif(browse_mode==230)
  141. @conditions << "individualCode=1"
  142. @page_title += " offering Private Instruction"
  143. elsif(browse_mode==240)
  144. @conditions << "classCode=1"
  145. @page_title += " offering Class Instruction"
  146. elsif(browse_mode==10)
  147. @order_by = 'sortCode ASC'
  148. @page_title += ' sorted by Value'
  149. elsif(browse_mode==20)
  150. @order_by = 'qualityCode DESC, sortCode ASC'
  151. @page_title += ' sorted by Quality'
  152. elsif(browse_mode==30)
  153. @order_by = 'costCode ASC, sortCode ASC'
  154. @page_title += ' sorted by Weekly Cost'
  155. elsif(browse_mode==35)
  156. @order_by = 'levelCode DESC, sortCode ASC'
  157. @page_title += ' sorted by Level of Instruction'
  158. elsif(browse_mode==40)
  159. @order_by = 'schoolSizeCode ASC, sortCode ASC'
  160. @page_title += ' sorted by School Size (small to large)'
  161. elsif(browse_mode==50)
  162. @order_by = 'classSizeCode ASC, sortCode ASC'
  163. @page_title += ' sorted by Class Size (small to large)'
  164. end
  165. end
  166. end
  167. ####################### PRIVATE METHODS #####################################
  168. private
  169. # returns the given value as String or Integer object, even if nil
  170. # nil Integers will return -1; nil String will return the empty string
  171. def non_nil(value, klass=String)
  172. return '' if nil && klass==String
  173. return -1 if nil && klass==Integer
  174. return value.to_i if klass==Integer
  175. return value.to_s if klass=String
  176. end
  177. def handle_param(value, db_col, should_equal, title, prepend_title=false)
  178. return if !value || value.blank?
  179. begin
  180. add_conditions=false
  181. if should_equal.kind_of?(Integer)
  182. if value.to_i==should_equal
  183. add_conditions = true
  184. end
  185. elsif should_equal.kind_of?(String)
  186. if value.to_s.eql?(should_equal)
  187. add_conditions = true
  188. end
  189. end
  190. if add_conditions
  191. @conditions << db_col + '=' + should_equal.to_s
  192. @page_title += title if !prepend_title
  193. @page_title = title + @page_title if prepend_title
  194. end
  195. rescue => e
  196. end
  197. end
  198. end