Rails 默认的数据 id 不是很安全,生成合适的 slug 很重要,对于中文来说显示拼音相对比较友好。以一个 Page 的数据为例说明。
一般关键的 gem 我都 fork 一份,防止以后不更新或者其他原因不能使用。
gem 'friendly_id',github: 'brucebot/friendly_id'
rails g migration add_slug_to_pages slug:string
rails g friendly_id
bunlde exec rake db:migrate
rails c
Page.find_each(&:save)
# config/initializers/friendly_id/slugged.rb
module FriendlyId
module Slugged
def normalize_friendly_id(value)
Pinyin.t(value.to_s).parameterize
end
end
end
class AddSlugToPages < ActiveRecord::Migration
def change
add_column :pages, :slug, :string
add_index :pages, :slug
end
end
class CreateFriendlyIdSlugs < ActiveRecord::Migration
def change
create_table :friendly_id_slugs do |t|
t.string :slug, :null => false
t.integer :sluggable_id, :null => false
t.string :sluggable_type, :limit => 50
t.string :scope
t.datetime :created_at
end
add_index :friendly_id_slugs, :sluggable_id
add_index :friendly_id_slugs, [:slug, :sluggable_type], length: { slug: 140, sluggable_type: 50 }
add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope], length: { slug: 70, sluggable_type: 50, scope: 70 }, unique: true
add_index :friendly_id_slugs, :sluggable_type
end
end
#page.rb
class Page < ActiveRecord::Base
extend FriendlyId
friendly_id :title, use: :slugged
def should_generate_new_friendly_id?
new_record? || slug.blank?
end
end
如果之前有写to_param的方法,请删除。
#pages_controller.rb
class PagesController < ApplicationController
def set_page
@page = Page.friendly.find(params[:id])
redirect_to action: [:edit,:show,:update,:destroy], id: @page.friendly_id, status: 301 unless @page.friendly_id == params[:id]
end
end
不要忘记在生产环境中运行
Page.find_each(&:save)