IT技術にまつわる実験ノート

「長編を書くより、短編を数多く完成させてください。それが上達への近道です」 by 手塚治虫

friendly_id を使ってみる

はじめに

ここでは、以下の記事を参考にして friendly_id を使ってみることにする。

 

使ってみる

ざっくりとアプリを作成する。

  • rails new friendly_id_sample
  • cd friendly_id_sample

 

friendly_id をインストールする。

  • echo "" >> Gemfile
  • echo "gem 'friendly_id'" >> Gemfile
  • bundle

 

サンプル用に Post モデルを作成する。

  • bin/rails g scaffold Post title:string body:text
  • bin/rails db:migrate

 

friendly_id のジェネレーターを実行する。

  • bin/rails generate friendly_id
  • bin/rails db:migrate

 

Post モデルに slug を追加する。

  • bin/rails g migration AddSlugToPosts slug:string:uniq
  • bin/rails db:migrate

 

app/models/post.rb を編集する。

f:id:matt-note:20190223002531p:plain

-> これで id カラムの代わりに、Post モデルの title カラムの値を URL の id とする設定をすることができる。


app/controllers/post_controller.rb を編集する。

f:id:matt-note:20190223002247p:plain

-> パラメータが id: "foo" の時、params[:id] の値は "foo" になる。この設定で、"foo"からレコードを検索できるようになる。

 

サーバーを起動して、データを投稿してみる。

f:id:matt-note:20190223002707p:plain

f:id:matt-note:20190223004804p:plain

-> show アクションのパラメータに id: "foo" としてアクセスしている。

 

大文字やスペースや記号を入れてみる。

f:id:matt-note:20190223010023p:plain

-> すべて小文字になり、ドットは削除されて、スペースは - を使うようになっている。

 

日本語のデータを投稿してみる。

f:id:matt-note:20190223003314p:plain

-> デフォルトだと、うまくいかない。

 

app/models/post.rb で normalize_friendly_id メソッドをオーバーライドする。

f:id:matt-note:20190223010938p:plain

f:id:matt-note:20190223011041p:plain

f:id:matt-note:20190223011130p:plain

-> URL で日本語を使えるようになった。

 

title 名を変更してアクセスしてみる。

f:id:matt-note:20190223012446p:plain

-> title を「アアア嗚呼亜」に変更したが、URL はそのまま以前の「あああ嗚呼亜」を使うようになっている。

 

この時、内部的には ActiveRecord::RecordNotFound が発生している。

f:id:matt-note:20190223012544p:plain

 

app/models/post.rb を変更する。

f:id:matt-note:20190223012918p:plain

f:id:matt-note:20190223013208p:plain

f:id:matt-note:20190223013230p:plain

-> エラーを発生させずにリダイレクトできるようになった。変更に対応するために、:history オプションは最初から指定して良いかもしれない。

 

ただし、ここで使えるのは最初に登録した URL となる。新しい titile 名の URL でアクセスするとエラーになる。

f:id:matt-note:20190223013902p:plain

 

:finders オプションを使ってみる。

friendly_id の v5 系から、:firnders オプションが使えるようになったとのこと。

app/models/post.rb を編集する。

f:id:matt-note:20190224043244p:plain

 

app/controllers/posts_controller.rb を修正する。

f:id:matt-note:20190224043347p:plain

f:id:matt-note:20190224043400p:plain

 

サーバーを起動して、アクセスしてみる。

f:id:matt-note:20190224043433p:plain

-> エラーもなく実行することができた。

 

詳しい点は、GitHub やドキュメントを確認すると良い。メンテナンスされている gem は、数年で仕様が変わるため、数年前の日本語情報を参考にすると、少し動作が異なるといったことがよくある。