Rails中的漂亮路径

我有一个类别模型,我使用默认的resources :categories脚手架来路由它resources :categories 。 我想知道是否有办法将路径从/category/:id更改为/category/:name 。 我补充说:

 match "/categories/:name" => "categories#show" 

routes.rb的资源行routes.rb并更改了控制器中的show动作:

 @category = Category.find_by_name(params[:name]) 

它有效,但是诸如link_to some_category之类的“魔术路径”仍然使用:id格式。

有没有办法做到这一点? 如果这是一个坏主意(由于rails在内部工作的一些可能方式),还有另一种方法可以实现吗? 那么/categories/music/categories/3都可以工作吗?

Rails有一个叫做to_param的漂亮的模型实例方法,它就是路径使用的方法。 它默认为id ,但你可以覆盖它并产生类似的东西:

 class Category < ActiveRecord::Base def to_param name end end cat = Category.find_by_name('music') category_path(cat) # => "/categories/music" 

有关更多信息,请查看to_param的Rails文档 。

编辑:

对于不适合URL的类别名称,您有多种选择。 正如你所说,一个是用连字符来表示空格,反之亦然。 但是,更安全的选择是在类表上创建名为name_param (或类似)的另一列。 然后,您可以使用它代替名称,以及所有路径和URL相关的业务。 使用parameterize inflector创建URL安全字符串。 我是这样做的:

 class Category < ActiveRecord::Base after_save :create_name_param def to_param name_param end private def create_name_param self.name_param = name.parameterize end end # Hypothetical cat = Category.create(:name => 'My. Kewl. Category!!!') category_path(cat) # => "/categories/my-kewl-category" # Controller @category = Category.find_by_name_param(param[:id]) #  

如果您不想破坏依赖于模型ID的现有代码,您可以像这样定义to_param:

  def to_param "#{id}-#{name}" end 

所以你的url将是: http:// path / 1-some-model ,你仍然可以使用Model.find(params [:id])加载模型,因为:

“123-hello-world”.to_i => 123

虽然可能超出了您的需要,但您可能还需要查看“人类可读url”支持,例如friendly_id或其中一个(例如,如果您需要unicode支持等),这些都在Ruby Toolbox中进行了描述。