使Rails资源和自定义路由冲突工作

时间:2012-02-18 21:47:42

标签: ruby-on-rails ruby-on-rails-3 routing

我是rails的新手,想知道如何才能完成这项工作。我希望网址看起来像这样:

http://localhost:3000/businesses/coldfire-gundam

使用这条路线:

match "/businesses/:permalink", :to => "businesses#show", :as => :business_permalink

然而,当我在此之前放置此路线时:

resources :businesses

对/ business / 1(1作为param [:id])的任何调用都不再起作用,显然是因为它被永久链接声明捕获

我怎么能让它发挥作用呢?

2 个答案:

答案 0 :(得分:2)

您需要一种区分/businesses/:id/businesses/:permalink的方法。 :id应始终为数字(当然,除非您使用的是MongoDB),因此如果您可以强制:permalink始终包含非数字的内容,那么简单的:constraints应该可以:

match '/businesses/:permalink', :to => 'businesses#show`, :constraints => { :permalink => /.*\D/ }, :as => :business_permalink

如果/.*\D/包含至少一个非数字字符,则:permalink强制路由仅匹配。您需要.*,因为路由正则表达式在开头隐式锚定。

如果您正在使用MongoDB,那么您的:id可能会是一个十六进制的BSON ID,因此您需要使用/.*\H/作为约束,并且您需要某种方法来确保:permalink始终包含至少一个非十六进制字符。

完成所有操作后,您可以将match "/businesses/:permalink"放在resources :businesses routes.rb之前routes.rb,一切都应该正常。我们会按照match中显示的顺序检查路由,因此您需要resources之前的{{1}}。

答案 1 :(得分:1)

我建议使用friendly_id gem创建永久链接路由。这将以一种易于重复使用的方式为您处理大部分“魔法”。

gem和railscast的资源: https://github.com/norman/friendly_id http://railscasts.com/episodes/314-pretty-urls-with-friendlyid