Rails中的漂亮路径

Jor*_*eña 2 seo routing ruby-on-rails

我有一个类别模型,我使用默认的脚手架来路由它resources :categories.我不知道是否有从改变路径的方式/category/:id/category/:name.我补充说:

match "/categories/:name" => "categories#show"
Run Code Online (Sandbox Code Playgroud)

在资源行上面routes.rb并改变show了控制器中的动作:

@category = Category.find_by_name(params[:name])
Run Code Online (Sandbox Code Playgroud)

它的工作原理,但"魔术路径" link_to some_category仍然使用:id格式.

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

von*_*rad 5

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"
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请查看to_paramRails文档.

编辑:

对于不适合URL的类别名称,您有多种选择.正如你所说,一个是gsub连字符的空格,反之亦然.但是,更安全的选择是在类别表上创建另一个名为name_param(或类似)的列.然后,您可以使用它代替名称,以及所有路径和URL相关的业务.使用parameterize变形器创建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]) # <Category id: 123, name: 'My. Kewl. Category!!!'>
Run Code Online (Sandbox Code Playgroud)