12
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Rails6.0] URLに数値のIDではなく(Qiitaみたいに)ハッシュ化したIDを使用する

Posted at

はじめに

showeditなどのアクションにアクセスする場合、user/1item/6のようにデフォルトでは数値のIDを使います。
このままだとユーザー数や投稿数が直接見えてしまい、かっこ良くなかったり過疎っているのがバレたりします。
今回はそんな問題を(Qiitaの記事のURLみたいに)IDをハッシュ化した文字列をURLに使用することで解決していきます。

モデルにカラムを作成

ハッシュ化なので、暗号化できても複合(元に戻す)ことは出来ません。
なので、まずはモデルにハッシュ化した文字列を入れるカラムを作成します。
今回はモデル名はUser、カラム名はid_digestとします。

$ bin/rails g migration add_id_digest_to_users

出来上がったmigrationファイルを編集します

XXXXXXXXXXXXX_add_id_digest_to_users.rb
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の値を埋めていくように実装します。

user.rb
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!

routes.rb
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

index.html.slim
= link_to('テスト', user_path(User.first))

成功すれば、URLにハッシュ化された文字列が入った状態でshoweditのページに遷移できていると思います。

まとめ

IDをハッシュ化することに関する情報が少なく、中々いい方法にたどり着けず苦戦しました。
まとめると
ハッシュ用のカラムを追加after_saveで自動的に値が入るよう修正
なのですが、何か他にいい方法があれば是非コメント等でご教授頂ければ幸いです。

参考文献

Ruby,Railsの暗号化いろいろ
https://railsguides.jp/active_record_callbacks.html

  1. MD5は弱点が発見されているハッシュ関数ですが、今回は解析されても問題のないidの値なので使用しました。

12
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?