Rails:如何处理状态和城市嵌套路由

时间:2011-11-07 20:45:55

标签: ruby-on-rails

我是Rails的新手(使用3.1),我希望有一个看起来像这样的网址:

domain.com/jobs/florida/orlando

我知道这不属于具有动作和一个id的典型路线,那么最好的方法是什么?这会属于嵌套路由吗?

更深入 - 如果有人点击/ jobs页面,他们会看到状态列表。如果他们点击/ jobs /佛罗里达页面,他们会看到一个城市列表。最后,如果他们打到/ jobs /佛罗里达/奥兰多,他们会看到奥兰多开设的工作列表。

我的路线会是什么样子?我应该以另一种方式考虑这种URL结构吗?我的主要动机是SEO - 这些页面通常不会被用户登录,只要他们通过搜索结果找到该网站。

谢谢!

3 个答案:

答案 0 :(得分:1)

您应该从rails指南中查看dynamic segments。基本上你的例子应该有这样的路线:

get "/jobs(/:state(/:city))", :to => "jobs#index"

并在index的{​​{1}}操作中检查您是否已选择州和城市。如果是,则显示该区域的作业列表,如果不是,则显示比当前级别更深的嵌套级别。

如果有帮助,您可以将此路线分散到3个不同的地方:

JobsController

或者你觉得,但我认为它过于设计并且第一个命题应该不会更难实现(特别是如果你有一个逻辑到before_filters,如果你有来自路线的特定段)

答案 1 :(得分:1)

我遇到了类似的问题并解决了它:

resources :jobs do
  collection do
    constraints :state_id => /[a-z\-]+/ do
      get ':state_id' => 'states#show', :as => :state
      get ':state_id/:city_id' => 'cities#show', :as => :city
    end
  end
end
  • /jobs将转到jobs#index

您的城市/州名不能包含数字!

  • /jobs/florida使用state_id =佛罗里达

  • 转到states#show
  • /jobs/new-york使用state_id = new-york

  • 转到states#show
  • /jobs/florida/orlando使用city_id = orlando

  • 转到cities#show

现在来了有趣的部分!您也可以使用slug作为您的工作:

  • /jobs/1234-experienced-senior-programmerjobs#show作为ID转到1234-experienced-senior-programmer,只需执行params[:id].to_i,您将获得ID 1234:)

不那么有趣的部分:

/jobs/new等收集方法将无法使用 - 您可以通过添加:state_id => /[a-z\-]{4,}/之类的量词来改变这种情况 这要求状态名称至少包含4个字符,并且所有3个字母的收集方法(如new)将照常传递给作业控制器

生成的路线:

state_jobs GET    /jobs/:state_id(.:format)     {:controller=>"states", :state_id=>/[a-z\-]+/, :action=>"show"}
 city_jobs GET    /jobs/:state_id/:city_id(.:format) {:controller=>"cities", :state_id=>/[a-z\-]+/, :action=>"show"}
      jobs GET    /jobs(.:format)               {:controller=>"jobs", :action=>"index"}
           POST   /jobs(.:format)               {:controller=>"jobs", :action=>"create"}
   new_job GET    /jobs/new(.:format)           {:controller=>"jobs", :action=>"new"}
  edit_job GET    /jobs/:id/edit(.:format)      {:controller=>"jobs", :action=>"edit"}
       job GET    /jobs/:id(.:format)           {:controller=>"jobs", :action=>"show"}
           PUT    /jobs/:id(.:format)           {:controller=>"jobs", :action=>"update"}
           DELETE /jobs/:id(.:format)           {:controller=>"jobs", :action=>"destroy"}

答案 2 :(得分:0)

如果您有一个固定的深度

,您可以在routes.rb文件中执行此操作
match 'jobs/:state/:city/:neighborhood' => "Jobs#show"

在你的表演行动中,你可以找到params [:state],params [:city]等,然后加载适当的工作。