我的网站上有搜索功能。结果页面将根据用户设置的结果给出分页结果,但不会按列标题对结果进行排序。
我可以点击它们并获得Desc / Asc箭头,但页面不会相应地对结果进行排序。
以下是结果页面:
.row-fluid#load_results_table
.span12
- if results.empty?
=render partial: 'no_results', locals: {search: search}
- else
%h1.page-header Search Results
- if results.count > 1000
%p= "Your search yielded many #{search.search_type.pluralize}"
- else
%p= "Your search yielded #{results.count} #{search.search_type.pluralize}"
=render partial: 'header_buttons', locals: {search: search}
%br
%br
= will_paginate results, :renderer => BootstrapPagination::Rails, id: "first_pagination"
%table.table.search_results.table-condensed.table-bordered.table-striped.sortable{:id => "#{search.search_type.pluralize}"}
%thead
%tr.search_header
%th= sortable_load "origin"
%th= sortable_load "dest"
%th= sortable_load "pickup"
%th= sortable_load "delivery"
%th= sortable_load "ltl"
%th= sortable_load "equipment_id", "Equipment"
%th= sortable_load "weight"
%th= sortable_load "length"
%th= sortable_load "rate"
-unless @search.origin.blank?
%th Estimated Deadhead Miles
%th Actions
%tbody
- results.each do |result|
%tr{:class => "#{search.search_type}_view", :id => "#{result['id']}" }
%td= Location.to_cs(result.origin)
%td= Location.to_cs(result.dest)
%td= format_date(result.pickup)
%td= format_date(result.delivery)
%td= full_or_par(result.ltl)
%td= result.equipment_id ? Equipment.to_equipment_name(result.equipment_id) : ""
%td= result.weight
%td= result.length
%td= result.rate
-unless @search.origin.blank?
%td= Location.distance_between(@search.origin.coords, result['origin'])
%td
.btn-group
%a.btn.btn-info{ :href => "/#{search.search_type.pluralize}/#{result['id']}" } Show
%a.btn{ :href => "javascript:void(0)", :class => "save", user_id: @search.user_id, :id => result['id']} Save
%a.btn.btn-primary{ :href => "javascript:void(0)", :class => "cover_link", :user_id=> @search.user_id } Cover
= will_paginate results, :renderer => BootstrapPagination::Rails
搜索模型
class Search < ActiveRecord::Base
attr_accessible :available, :delivery, :dest, :length, :ltl, :origin, :pickup, :rate, :search_type, :user_id, :weight, :expiration, :pickup_operator, :delivery_operator, :expiration_operator, :available_operator, :length_operator, :rate_operator, :weight_operator, :origin_zip, :dest_zip, :origin_radius, :dest_radius, :saved, :date_posted, :order_by, :origin_cs, :results, :dest_cs, :origin_states, :dest_states, :origin_id, :dest_id, :equipment_ids, :temp_origin, :temp_dest, :temp_equipment
attr_accessor :origin_cs, :dest_cs, :log
before_validation :convert_cs_to_id
OPERATORS = ["<=","<",">=",">","=","!="]
NUMERICALITY_MESSAGE = "Needs to be a number"
LOCATION_FORMAT_MESSAGE = "Location must be in format (city,ST)"
LOCATION_PRESENCE_MESSAGE = "Location does not exist"
validates_inclusion_of :pickup_operator, in: OPERATORS
validates_inclusion_of :delivery_operator, in: OPERATORS
validates_inclusion_of :expiration_operator, in: OPERATORS
validates_inclusion_of :available_operator, in: OPERATORS
validates_inclusion_of :length_operator, in: OPERATORS
validates_inclusion_of :rate_operator, in: OPERATORS
validates_inclusion_of :weight_operator, in: OPERATORS
validates_inclusion_of :search_type, in: ["load","truck"]
validates_numericality_of :rate, {allow_nil: true, message: NUMERICALITY_MESSAGE}
validates_numericality_of :origin_radius,{allow_nil: true, message: NUMERICALITY_MESSAGE}
validates_numericality_of :dest_radius, {allow_nil: true, message: NUMERICALITY_MESSAGE}
validates_numericality_of :weight, allow_nil: true, message: NUMERICALITY_MESSAGE
validates_numericality_of :length, allow_nil: true, message: NUMERICALITY_MESSAGE
validates_presence_of :search_type
validates_presence_of :origin_id, :if => :origin_cs?
validates_presence_of :dest_id, :if => :dest_cs?
belongs_to :user
has_and_belongs_to_many :equipment
belongs_to :origin, class_name: "Location", foreign_key: :origin_id
belongs_to :dest, class_name: "Location", foreign_key: :dest_id
def search(page)
where = []
where << PrepareSearch.states("dest", self.dest_states) unless self.dest_states.blank?
where << PrepareSearch.states("origin", self.origin_states) unless self.origin_states.blank?
where << PrepareSearch.location('origin', self.origin.coords, self.origin_radius) unless self.origin.blank?
where << PrepareSearch.location('origin', self.origin.coords, self.origin_radius) unless self.origin.blank?
where << PrepareSearch.zip('origin', self.origin_zip, self.origin_radius) unless self.origin || self.origin_zip.blank?
where << PrepareSearch.location('dest', self.dest.coords, self.dest_radius) unless self.dest.blank?
where << PrepareSearch.zip('dest', self.dest_zip, self.dest_radius) unless self.dest || self.dest_zip.blank?
where << PrepareSearch.equipment(self.equipment_ids) unless self.equipment_ids.blank?
where << PrepareSearch.date('created_at', self.date_posted, '>=') unless self.date_posted.blank?
if self.search_type == 'load'
select = "loads.id, origin, dest, pickup, delivery, ltl, equipment_id, weight, length, rate"
where << PrepareSearch.date('pickup', self.pickup, self.pickup_operator) unless self.pickup.blank?
where << PrepareSearch.date('delivery', self.delivery, self.delivery_operator) unless self.delivery.blank?
where << PrepareSearch.attribute('length', self.length, self.length_operator) unless self.length.blank?
where << PrepareSearch.attribute('rate', self.rate, self.rate_operator) unless self.rate.blank?
where << PrepareSearch.attribute('weight', self.weight, self.weight_operator) unless self.weight.blank?
where << PrepareSearch.attribute('ltl', self.ltl, '=') unless self.ltl.blank?
elsif self.search_type == 'truck'
select = "trucks.id, origin, dest, available, expiration, equipment_id, comments"
where << PrepareSearch.date('available',self.available,self.available_operator) unless self.available.blank?
where << PrepareSearch.date('expiration',self.expiration,self.expiration_operator) unless self.expiration.blank?
end
where << "covered=false AND deleted=false"
where = where.join(' AND ')
order = self.order_by ? self.order_by + " desc" : ""
limit = "LIMIT=200"
Module.const_get(self.search_type.capitalize).where(where).select(select).limit(limit).order(order).page(page).per_page(25)
end
module PrepareSearch
def PrepareSearch.equipment(equipments)
eq = ""
equipments.each {|e| eq += "'#{e}'," }
eq = eq[0..-2]
"equipment_id IN (#{eq})"
end
def PrepareSearch.attribute(attribute, value, comparison)
"#{attribute} #{comparison} #{value}"
end
def PrepareSearch.date(type, date, comparison)
if comparison == '='
"CAST(#{type} as TEXT) LIKE '%#{date.strftime("%F")}%'"
elsif comparison == '<='
"#{type} #{comparison} '#{date.strftime("%F")} 23:59:59'"
else
"#{type} #{comparison} '#{date.strftime("%F")}'"
end
end
def PrepareSearch.zip(type, zip, radius)
location = Location.where(zip: zip).first
if location
"(ST_Distance(#{type}, ST_GeographyFromText('POINT( #{location.coords.x} #{location.coords.y} )')) <= #{radius.to_f*1609.334})"
else
#if no locations match zip search for location that will never exist.
"(ST_Distance(#{type}, ST_GeographyFromText('POINT( 1 1 )')) <= #{radius.to_f*1609.334})"
end
end
def PrepareSearch.location(type, location, radius)
"(ST_Distance(#{type}, ST_GeographyFromText('POINT( #{location.x} #{location.y} )')) <= #{radius.to_f*1609.334})"
end
def PrepareSearch.states(type, states)
states = states.split(",")
st = ""
states.each {|s| st += "'#{s}'," }
st = st[0..-2]
"#{type}_state IN (#{st})"
end
end
@log = Logger.new("#{Rails.root}/log/searches.log")
@log.datetime_format = "%F %T"
private
def convert_cs_to_id
temp_origin = Location.where(cs: self.origin_cs.downcase) unless self.origin_cs.blank?
self.origin_id = temp_origin.blank? ? "" : temp_origin.first.id
temp_dest = Location.where(cs: self.dest_cs.downcase) unless self.dest_cs.blank?
self.dest_id = temp_dest.blank? ? "" : temp_dest.first.id
end
def origin_cs?
errors.add(:origin_cs, "not a valid location") if !origin_cs.blank? && origin_id.blank?
origin_cs.blank? ? false : true
end
def dest_cs?
errors.add(:dest_cs, "not a valid location") if !dest_cs.blank? && dest_id.blank?
dest_cs.blank? ? false : true
end
end
更新
当我点击列标题时,页面网址将更改为
http://www.sitename.com/searches/23616?direction=desc&sort=pickup