gem FriendlyIdについて
FriendlyId Guideがあるので一部抜粋したものを翻訳します。
FriendlyIdはRubyのActive Recordのアドオンで、URLのidを文字列に置き換えることができます。
FriendlyIdを使用しない場合
http://example.com/states/4323454
with FriendlyId
http://example.com/states/washington
人間が読めるキーワードを使ってページを識別するURLの部分を作成します。
これにより、ユーザーにとっても検索エンジンにとっても、アプリケーションをよりフレンドリーなものにすることができます。
gemの名前のFriendlyIdの由来はここから付けられたものだと言うことがわかりますね。
実装の例
弊社のサービスCarelyでも実際にfriendly_idを使用しているので紹介したいと思います。
class Customer < ApplicationRecord
include FriendlyId ---- ①
friendly_id :uuid, use: :finders ---- ②
①modelで FriendlyId を使用するには、まず FriendlyId moduleをincludeする必要があります。
②これはuuidでactiverecordのfind methodを使えるようにする記述です。
customer: {
id: 10,
uuid: "28d0d2b8-3f2c-49d0-bf11-3b01ec164311"
firstName: "hogehoge",
lastName: "fugafuga",
mailAddress: "hogehoge@example.com",
age": "30"
・
・
・
}
上記のようなcsutomerのデータがあったとします。
本来findは主キー(id)しか対応していないため
customer = Customer.find(10)
のような記述になりますが、
friendly_id :uuid, use: :finders
を記述することで
customer = Customer.find("28d0d2b8-3f2c-49d0-bf11-3b01ec164311")
とuuidでもfind methodを使用することができます。
また、URLについても該当のcustomerの情報を表示する場合に
http://example.com/customer/10
となっていましたがFriendlyIdを使用することで
http://example.com/customer/28d0d2b8-3f2c-49d0-bf11-3b01ec164311
となります。
FriendlyIdを使うメリットではFriendlyId Guideに記載されているように
FriendlyIdを使用しない場合
http://example.com/states/4323454
with FriendlyId
http://example.com/states/washington
と名前をURLに含ませることで識別しやすくなる点もあるのですが弊社のようにuuidを使うことで何番目のデータだと推測できなくなり、テーブルのサイズを推測することもできなくなるというメリットもあります。
またsluggedという機能を使うとURLをフォーマットすることもできます。
FriendlyId Guideに記載されていた例では以下のようにtitleへスペース入りの文字列を入れた場合、本来はURLは/posts/this%20is%20the%20first%20post
のようになっているはずですがSluggedを使用することで /posts/this-is-the-first-post
と見やすくなります。
# a migration
class CreatePosts < ActiveRecord::Migration
def self.up
create_table :posts do |t|
t.string :title, :null => false
t.string :slug, :null => false
t.text :body
end
add_index :posts, :slug, :unique => true
end
def self.down
drop_table :posts
end
end
# model
class Post < ActiveRecord::Base
extend FriendlyId
friendly_id :title, :use => :slugged
end
# Sluggedを使うことで整形され見やすくなる
@post = Post.create(:title => "This is the first post!)
@post.friendly_id # "this-is-the-first-post "を返します。
redirect_to @post # URLは/posts/this-is-the-first-postになります。
注意点
model内でFriendlyIdを使っているかどうかはちゃんと記述を見て判断しましょう。
大体のmodelでFriendlyIdを使ってるからこのmodelでも使ってるだろうという先入観で使うと???となる(なった)というお話です。
例えばcompanyというmodelではuuidというカラムがあるがFriendlyIdとして使っていなかった場合
company = Company.find("16d28548-2e57-4e67-a041-1f05acfdabba")
みたいに記述すると
company = Company.find(16)
の結果が表示されます。
これはfind methodが引数に文字列を渡した場合に.to_i
で整数に変換しているからだと思われます。
エラーになればFriendlyIdを使っていないんだなと分かるのですが
データが返ってきたので正常にuuid = "16d28548-2e57-4e67-a041-1f05acfdabba"
のデータが取れたのだと一瞬間違ってしまいますね。