【问题标题】:How to set up routes / link like this?如何设置这样的路线/链接?
【发布时间】:2010-12-24 07:31:17
【问题描述】:

看看haystack

如果您点击 $3,000 并查看以下网址,它将是:

“3000 下”

假设您使用的是Search Logic,这将如何在路由中完成?

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

让我感到困惑的是,他们如何将其范围扩展到任何城市,例如 /los-angeles/3000-under,但一旦我看到路线,它可能会更有意义。

下一个问题,处理他们呈现当前活动路线的最佳方式是什么?

例如,如果您点击“任何预算”并重定向,那里会显示“任何预算”,如果您点击“3000 及以下”​​,它会重定向,然后那里会显示“3000 及以下”​​。我假设它们与 url 匹配并在其中显示适当的文本?

【问题讨论】:

  • “看看链接文本”吧?? “他们”是谁?完全糊涂了。
  • 已更新,链接因格式化而消失。对不起。
  • 这不是 URL 中的参数的用途吗?似乎不是您在路径中要处理的事情。
  • @Ryan Bigg:虽然这是参数的用途。但参数不会创建用户友好的 URL。这个问题是关于 Rails 路由允许部分路径被视为参数的。

标签: ruby-on-rails routing


【解决方案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 的连线的路线都将使用动态查找器。

超级双倍奖励:这些动态搜索可以与关联和命名范围链接起来。

【讨论】:

  • 好吧,我想利用搜索逻辑。它们自动提供了许多命名范围。这就是我的参数 ?search[price_greater_than]=999&search[price_less_than]=9001 我不知道如何在我的路线中映射它,以便我可以让它显示类似 /999-to-9001 我是还认为这可能必须为每个范围命名路由,还是有更聪明的方法?
  • 尽管这不是您在原始问题中所要求的。我已经更新了答案。
猜你喜欢
  • 2016-10-05
  • 2012-06-28
  • 2022-12-04
  • 2013-08-12
  • 1970-01-01
  • 2011-11-18
  • 2020-08-18
  • 2013-05-15
  • 1970-01-01
相关资源
最近更新 更多