はじめに
show
やedit
などのアクションにアクセスする場合、user/1
やitem/6
のようにデフォルトでは数値のIDを使います。
このままだとユーザー数や投稿数が直接見えてしまい、かっこ良くなかったり過疎っているのがバレたりします。
今回はそんな問題を(Qiitaの記事のURLみたいに)IDをハッシュ化した文字列
をURLに使用することで解決していきます。
モデルにカラムを作成
ハッシュ化なので、暗号化できても複合(元に戻す)ことは出来ません。
なので、まずはモデルにハッシュ化した文字列を入れるカラムを作成します。
今回はモデル名はUser
、カラム名はid_digest
とします。
$ bin/rails g migration add_id_digest_to_users
出来上がったmigrationファイルを編集します
class AddIdDigestToUsers < ActiveRecord::Migration[6.0]
def change
add_column :users, :id_digest, :string
end
end
保存したらmigirate
$ bin/rails db:migrate
モデルの編集
次に、モデルのファイルを編集していきます。
ここでのポイントは、IDはsaveが終わった後に値が入る
という点です。
なのでsave
メソッドが完了した後にid_digest
の値を埋めていくように実装します。
class User < ApplicationRecord
after_save :create_id_digest # saveが完了した後に呼び出されるコールバック
def to_param
id_digest
end
private
# after_saveによって呼び出されるメソッド
def create_id_digest
if id_digest.nil?
new_digest = Digest::MD5.hexdigest(id.to_s)
update_column(:id_digest, new_digest)
end
end
end
after_save
コールバックでcreate_id_digest
メソッドを呼んています。
このメソッド内の
new_digest = Digest::MD5.hexdigest(id.to_s)
でIDの値を元にMD5
でハッシュ化しています。1
あとはupdate_column
メソッドでvalidationをスキップして値を保存しています。
こうしておかないと、後々カラムやvalidationを増やした時にここでvalidationエラーが出てしまいます。
また、to_param
メソッドをオーバライドしてURLに使用する値を変更しています。
これに関しては以下のサイトが参考になるかと思います。
https://ruby-rails.hatenadiary.com/entry/20141223/1419334845
to_key と to_param で URL や HTML 中のリソースの id を別の文字列にしてしまう
ページにアクセス
あとはルーティングを設定して、ページにアクセスするリンクからページに遷移すればOK!
Rails.application.routes.draw do
resources :users
root 'user#index'
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
= link_to('テスト', user_path(User.first))
成功すれば、URLにハッシュ化された文字列が入った状態でshow
やedit
のページに遷移できていると思います。
まとめ
IDをハッシュ化することに関する情報が少なく、中々いい方法にたどり着けず苦戦しました。
まとめると
ハッシュ用のカラムを追加
→after_saveで自動的に値が入るよう修正
なのですが、何か他にいい方法があれば是非コメント等でご教授頂ければ幸いです。
参考文献
Ruby,Railsの暗号化いろいろ
https://railsguides.jp/active_record_callbacks.html
-
MD5は弱点が発見されているハッシュ関数ですが、今回は解析されても問題のないidの値なので使用しました。 ↩