【问题标题】:Pretty Paths in RailsRails 中的漂亮路径
【发布时间】:2011-01-19 07:31:45
【问题描述】:

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

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

routes.rb 中的资源行上方,并将控制器中的show 操作更改为:

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

它可以工作,但像link_to some_category 这样的“魔法路径”仍然使用:id 格式。

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

【问题讨论】:

    标签: ruby-on-rails routing seo


    【解决方案1】:

    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"
    

    更多信息,请查看Rails documentation for to_param

    编辑:

    当涉及到不适合 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!!!'>
    

    【讨论】:

    • 非常感谢!我忘记了这个!
    • 您是否知道在类别中处理空格的好方法?那么例如,一个类别“两个词”,使其成为 url 中的“两个词”?这是否需要我做 to_param name.gsub(" ", "-") 然后每次我想 find_by_name 我做同样的事情? params[:name].gsub("-", "")?我将如何重写我的匹配模式?
    • 我发现 rails 中有一个 parameterize 方法,它应该比我想的 gsub'ing 更好。
    • 哇,非常感谢 vonconrad,这很有意义。非常感谢您的帮助!
    【解决方案2】:

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

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

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

    "123-hello-world".to_i => 123

    【讨论】:

      【解决方案3】:

      虽然可能超出您的需要,但您可能还想研究“人类可读的 url”支持,如friendly_id 或here at Ruby Toolbox 中描述的其他一种(例如,如果您需要 unicode 支持等)。

      【讨论】:

        猜你喜欢
        • 2021-04-26
        • 2012-05-26
        • 1970-01-01
        • 2011-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-02
        • 2013-06-08
        相关资源
        最近更新 更多