如何设置这样的路线/链接?

时间:2009-12-08 06:26:35

标签: ruby-on-rails routing

查看haystack

如果点击$ 3,000,请查看该网址:

“3000-下”

假设您正在使用Search Logic,这将如何在路线中完成?

默认情况下,为了快速参考,搜索逻辑建议搜索映射到模型字段的[:params]。例如,Haystack的案例:{:search => {:price_less_than => '3000'}}

还有什么让我感到困惑的是他们如何将它扩展到像/ los-angeles / 3000-under这样的城市,但是一旦我看到它可能更有意义的路线。

下一个问题,处理目前哪条路线有效的最佳方式是什么?

例如,如果您单击“任何预算”并重定向,它会在那里说“任何预算”,如果您点击“3000及其下”,它将重定向,然后在那里说“3000及其下”。我假设它们与网址匹配并显示内联的相应文本?

1 个答案:

答案 0 :(得分:1)

如果没有看到路由/控制器,则无法确定,但它看起来像是一些默认路由滥用。

您可能会注意到只是在该预算下拉列表中输入未暗示的网址实际上并未缩小结果范围。我不认为它使用任何复杂的搜索逻辑,我的猜测是它只是命名范围。

路线:

map.connect ':location/:terms', :controller => "companies", :action => "for_location"
map.connect ':terms', :controller => "companies", :action => "for_budget" 

然后公司控制器可能会设置如下:

def for_location
  @location = Location.find_by_name(params[:location])
  @companies = case params[:terms]
  when /3000-under|3000-to-10000|10000-to-25000|25000-to-50000|50000-above/
    @location.companies.send(params[:terms])
  else 
    @location.companies
  end
end

def for_budget
  @companies = case params[:terms]
  when /3000-under|3000-to-10000|10000-to-25000|25000-to-50000|50000-above/
    Companies.send(params[:terms])
  else 
    @companies = Companies.all
  end
end

命名范围定义为:

class Company < ActiveRecord::Base
  ...
  named_scope :3000-under, :conditions => "budget <= 3000"
  named_scope :3000-to-10000, :conditions => "budget >= 3000 AND budget <= 10000"
  named_scope :3000-to-10000, :conditions => "budget >= 10000 AND budget <= 25000"
  named_scope :3000-to-10000, :conditions => "budget >= 25000 AND budget <= 50000"
  named_scope :3000-to-10000, :conditions => "budget >= 50000"
end

编辑:因为制作这个动态是一个有趣的问题...

只需付出更多努力,您就可以使整个搜索变得动态。

路线:

map.connect ':location/:term1-:term2', :controller => "companies",
   :action => "for_location", :term1 => /\d+|under|above/, :term2 => /\d+/
map.connect ':term1-:term2', :controller => "companies", :action => "for_budget", 
   :term1 => /\d+|under|above/, :term2 => /\d+/

控制器:

def for_location
  @location = Location.find_by_name(params[:location])
  @companies = @location.companies.send("search_#{params[:term1]}_#{params[:term2]}")
end

def for_budget
  @companies = Companies.send("search_#{params[:term1]}_#{params[:term2]}")
end

模型:

def self.method_missing(method, *args)
  if method.match(/^search_(under|above|\d+)_(\d+)$/)
     first_term, second_term = $1, $2
     if first_term == "under"
       self.find(:conditions => ["price <= ? ", second_term])
     elsif first_term == "above"
       self.find(:conditions => ["price >= ? ", second_term])
     else
       self.find(:conditions => ["price >= ? AND price <= ?", 
         *[first_term,second_term].sort])
     end
  else
   super(method, *args)
  end
end

现在,任何匹配/:location / 300-400或/:location / under-5000或/ above-27的battern的路线都将使用动态查找器。

Super Double Bonus:这些动态搜索可以使用关联和命名范围进行链接。