Rails中使用Friendlyid和Chinese_pinyin生成中文友好的slug

Rails默认的数据id不是很安全,生成合适的slug很重要,对于中文来说显示拼音相对比较友好。以一个Page的数据为例说明。

Gemfile

一般关键的gem我都fork一份,防止以后不更新或者其他原因不能使用。

gem 'friendly_id',github: 'brucebot/friendly_id'

Console

rails g migration add_slug_to_pages slug:string  
rails g friendly_id  
bunlde exec rake db:migrate  
rails c  
Page.find_each(&:save)  

friendly_id的Slugged中文处理

# config/initializers/friendly_id/slugged.rb
module FriendlyId  
module Slugged  
  def normalize_friendly_id(value)
    Pinyin.t(value.to_s).parameterize
  end
end  
end  

Migration

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  

Model

#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的方法,请删除。

Controller

#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)

-END-

QIAN Yong

热衷于接触各类有趣尖端的机器人应用,也乐于去发现处理这类应用中的问题;同时我热衷于接触先进的IT技术,这个博客就是我了解与熟悉,并解决这些问题的过程记录。
公众号:myxulung

Hangzhou,China http://qianyong.me