3
1

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 1 year has passed since last update.

Ruby On Rails で 主キーに UUID を使用する

Last updated at Posted at 2022-09-19

Ruby On Rails とは?

  • Ruby On Rails (以下、Rails)についてはこちらをご確認下さい。

UUID とは何か?

  • UUID とは Universally Unique IDentifier のことで普遍的な一意の識別子のことを指す。

なぜ Rails で主キーに UUID を使用するのか? 

  • 例えば MySQL であれば主キーに AUTO_INCREMENT を使用するケースが多いと思いますが、そうすると該当ページへアクセスする場合、 Rails では URL が https://example.com/users/1 というようになってしまい、 1 の部分が 2 だったらどうなのか、 10100 だったらどうなのか・・・というような感じで簡単に推測されてしまいます。
  • cancancanpundit のような権限管理 gem を使用することで URL が推測されてもアクセス不可にさせることもできますが、認証/認可していることが前提となってしまう為、例えばログインはしなくてもいいけれど URL を知っている人だけにアクセスさせたいというようなことができません。
  • そこで、今回は URL を知っている人だけにアクセスさせることを実現できるようにしつつ、URL を推測できないようにする為に主キーに UUID を使用します。
    該当ページへアクセスする場合の URL が https://example.com/users/9332ba51-d7de-4661-acb9-a1b481917dd4 のようになり、推測不可能になります。

ソースコード

  • app/models/concerns/uuid_module.rb を作成して下記のように記述する
    • 各々のモデルで使用したい為、モジュール化して concerns/ 配下に配置
    • 何らかの理由で id が存在しないテーブルに対して create してもエラーにならないように has_attribute?(:id) を行い、 id が存在する場合のみ uuid を生成する
    • 滅多にないが生成された id が既に存在した場合は再生成する
module UuidModule
  extend ActiveSupport::Concern

  included do
    before_create :generate, if: -> { has_attribute?(:id) }
  end

  def generate
    self.id ||= loop do
      uuid = SecureRandom.uuid
      break uuid unless self.class.exists?(id: uuid)
    end
  end
end
  • app/models/application_record.rb の上部へ include UuidModule を記述
class ApplicationRecord < ActiveRecord::Base
  include UuidModule

  # ...
end

留意事項

  • マイグレーションの際には主キーは必ず36文字の文字列が保存可能な型にする
class CreateUsers < ActiveRecord::Migration[7.0]
  def change
    create_table :users, id: :string, limit: 36 do |t|
    # ...
    end
  end
end

まとめ

  • 上記のようにすることでデータ新規保存の際には id が推測不可能な文字列になり、該当ページへアクセスする際には冒頭述べたような https://example.com/users/9332ba51-d7de-4661-acb9-a1b481917dd4 になります。
    • 該当ページがない場合は $ rails g scaffold_controller user などで作成後、レコードを新規作成した上で詳細ページへアクセスしてみて下さい。
3
1
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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?