我在我的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
答案 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中看到不必要的数字。它还可以按部分,按年,按月访问文章,显然,显示文章本身。您可能希望通过单一路线处理所有内容,如链接中所述,但这取决于您。
希望这有帮助!