Friendly_Id slugs with id或以斜杠分隔的日期

时间:2014-01-22 18:01:16

标签: ruby-on-rails friendly-id

我在我的Rails 4应用程序中使用Friendly_Id 5 gem来使URL“更友好”。我现在可以生成像/ article / my-article-title这样的网址。在今天的许多博客上,您还可以在路径中看到日期或ID。我如何生成以下网址:

 /articles/23/my-article-title 

其中23是文章ID。似乎slug实际上必须是23/my-article-title,因为slug必须在DB中是唯一的。或者我如何生成基于日期的slug?

 /articles/2014/01/22/my-article-title 

2 个答案:

答案 0 :(得分:1)

我不会将文章的日期放在网址中,因为有些人会因为未创建的内容而被抛弃,例如,在一周之内,这样可能会为您带来更少的流量。

但是,我建议将ID放在标题旁边。我不确定如何使用friendly_id来做这件事,但在我看来,这是一个更好的方法。我自己从friendly_id slugs切换到这个方法。

只需在模型中定义to_param

def to_param
   "#{id}-#{title.parameterize}"
end

Rails将自动使用id

找到Model.find(params[:id])

答案 1 :(得分:1)

我最终做了以下事情。

在我的 routes.rb 文件中:

resources :articles, except: [:index, :show]
constraints section: /section|anothersection|somethingelse/ do
  constraints year: /\d{4}/ do
    constraints month: /\d{1,2}/ do
      resources :articles, only: :show, path: '/:section/:year/:month', as: :my_articles
      get ':section/:year/:month', to: 'articles#by_month', as: :month
    end
    get ':section/:year', to: 'articles#by_year', as: :year
  end
  get ':section', to: 'articles#by_section', as: :section
end

有人建议我do this differently,但我最后只是使用我的版本,因为这允许我直接向路线添加约束。它在视觉上更加清晰,看看我对这条路线筑巢的意图是什么。

在我的article.rb 模型文件中,我有类似的内容:

class Article < ActiveRecord::Base
    def slugify
        to_remove = %w(a an as at before but by for from is in into like of off on onto per since than the this that to up via with)
        title.downcase.split.reject {|word| to_remove.include?(word)}.collect {|word| word.gsub(/[:,\-\.’']/,'')}.join(' ').parameterize
    end

    def to_param
        slug
    end
end

我制作了slugify方法,其行为类似于Drupal的默认slug生成器。这是在slug列中保存到数据库的内容。然后,to_param方法调用此字段以生成文章slug。

至于我的数据库 schema.rb 文件,重要的部分字面上归结为创建slug列并为其编制索引:

create_table "articles", force: true do |t|
  t.string   "title"
  t.text     "body"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.integer  "user_id"
  t.string   "section"
  t.string   "slug"
end

add_index "articles", ["slug"], name: "index_articles_on_slug", unique: true

我的控制器看起来像:

class ArticlesController < ApplicationController
  before_action :set_section, only: [:by_month, :by_year, :by_section]

  #I'm using the by_star gem to make the by_year and by_month part easy!
  def by_month
    @articles = Article.by_month(params[:month]).by_year(params[:year]).by_section(@section)
  end

  def by_year
    @articles = Article.by_year(params[:year]).by_section(@section)
  end

  def by_section
    @articles = Article.by_section(@section)
  end

  private
  def set_section
    @section = params[:section]
  end
end

结果

正如我所解释的那样,避免了在slug中看到不必要的数字。它还可以按部分,按年,按月访问文章,显然,显示文章本身。您可能希望通过单一路线处理所有内容,如链接中所述,但这取决于您。

希望这有帮助!