[Rails]Model(ActiveRecord)のid(PK)にULIDを用いる
概要
なぜULIDを使うか?というモチベーションはこちらの記事をご覧ください。
やり方
1. Gem ulid をインストールする
Gemfile
gem 'ulid'
( gem 'ulid', '~> 1.3.0'
のようにバージョン指定する方が好ましいです)
これで bundle install すると、以下のように ULID が生成できるようになります。
> ULID.generate
=> "01FZR8MM88EG6Q35H854F4F5B3"
2. ULID を PK として扱いたいテーブルのマイグレーションファイルを作成する
通常のマイグレーションファイルの作成・記述・実行方法は割愛します。
マイグレーションファイルでは String の PK にして長さ 26 文字※1とします。
db/migrate/yyyymmddhhmmss_create_user.rb
class CreateUser < ActiveRecord::Migration[6.1]
def change
create_table :users, id: false do |t|
t.string :id, null: false, limit: 26, primary_key: true, comment: 'ID'
end
end
end
※1. ULID の長さは26文字です
3. ULID を PK として扱う Concern を作成する
複数のモデルクラスで同様のコードを書くことになるので、 Concern で ULID に関する処理をまとめておきます。
Concern ではなく、 ApplicationRecord にまとめておくこともできますが、他のIDを用いたいとなった場合※2に面倒なので、 Concern にしておきます。
app/models/concerns/ulid_pk.rb
module UlidPk
extend ActiveSupport::Concern
included do
after_initialize :set_id
end
def set_id
id = ULID.generate
end
end
after_initialize で id をセットするように書いておくと、 create の際に他のカラムで id の値を扱えるので便利です。
※2. 例えば、Stripeなど外部のSaaSのオブジェクトのIDをDBで格納しておく場合などにidカラムの値をSaaS側のオブジェクトのidと揃えたいといったケースが考えられます。
3. id は readonly にしておく
id は readonly にしておきます。
app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
attr_readonly :id
end
上書きすることがないので、上書きできないようにしておきます。
各モデルで定義するのは手間なので、定義する場所は ApplicationRecord で良いと思います。
4. Concern を include する
app/models/user.rb
class User < ApplicationRecord
include UlidPk
attribute :id, :string
validates :id, length: { is: 6 }, presence: true, uniqueness: true
end
id カラムのバリデーションはできれば半角英数字でULIDに用いられる可能性のある文字列のみで判定したいですし、 ActiveModel::EachValidator で ULID かどうか判定するバリデーションを定義するのがスマートですが、この記事ではそれは割愛します。
以上でModel(ActiveRecord)のid(PK)にULIDを用いることができます。
.find() や .order(:id) も AUTO INCREMENT のときと使用感変わらず使えます。
Author And Source
この問題について([Rails]Model(ActiveRecord)のid(PK)にULIDを用いる), 我々は、より多くの情報をここで見つけました https://zenn.dev/isao_e_dev/articles/93e8e78c02b15a著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol