Rails Rails 中使用 friendly_id 和 chinese_pinyin 生成中文友好的 slug

brucebot · 2016年03月10日 · 最后由 brucebot 回复于 2017年02月24日 · 3015 次阅读

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)

请问 Page.find_each(&:save) 的作用是什么啊

gavin1818 回复

把和 page 相关的新的数据都更新一下

需要 登录 后方可回复, 如果你还没有账号请 注册新账号