LoginSignup
3
1

More than 3 years have passed since last update.

【Rails】ModelのPrimary keyをULIDにする【ActiveRecord】

Posted at

RailsのModelはPrimary keyに何も指定をしないとidカラムがPrimary keyとなります。(サロゲートキー)
idカラムの値はインクリメントされていくのですが、本記事はidカラムの値をインクリメントされる値から、ULIDに変更する方法です。

環境

Ruby: 2.7.2
Rails: 6.1.1
DB: PostgreSQL 13.1
ライブラリ: ULID

手順

  1. カラムの型を変更(Migration)
  2. Modelに追記
  3. テスト

Migration

class CreateUsers < ActiveRecord::Migration[6.1]
  def change
    # idカラムをstringにする
    create_table :users, id: :string do |t|
      t.string :name, null: false

      t.timestamps
    end
  end
end

Model

models/user.rb

class User < ApplicationRecord
  include Identifiable
end
models/concerns/identifiable.rb
module Identifiable
  extend ActiveSupport::Concern

  included do
    # memo: primary_keyのデフォルトの値は`id`
    attribute primary_key, :string, default: -> { ULID.generate }
  end
end


実行結果

irb(main):001:0> User.new
=> #<User id: "01EX96S3Q185V0FSMFCCJBKN6P", name: nil, created_at: nil, updated_at: nil>

irb(main):006:0> User.create(name: 'name')
  TRANSACTION (0.2ms)  BEGIN
  User Create (0.5ms)  INSERT INTO "users" ("id", "name", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["id", "01EX95SNJ85JX57H8F43JEAGPG"], ["name", "name"], ["created_at", "2021-01-30 08:15:51.880899"], ["updated_at", "2021-01-30 08:15:51.880899"]]
  TRANSACTION (3.6ms)  COMMIT
=> #<User id: "01EX95SNJ85JX57H8F43JEAGPG", name: "name", created_at: "2021-01-30 08:15:51.880899000 +0000", updated_at: "2021-01-30 08:15:51.880899000 +0000">

テスト

spec/models/user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  it_behaves_like 'Identifiable'
end
spec/support/models/identifiable.rb

RSpec.shared_examples 'Identifiable' do
  describe '#primary_key' do
    context 'primary_keyカラムが`id`の場合' do
      subject { described_class.new.id }

      it { is_expected.to match(/[0-9A-Z]{26}/) }
    end
  end
end

参考

https://github.com/rails/rails/blob/5f3ff60084ab5d5921ca3499814e4697f8350ee7/activerecord/lib/active_record/attribute_methods/primary_key.rb#L89
https://api.rubyonrails.org/classes/ActiveRecord/Attributes/ClassMethods.html
https://github.com/shin1rok/ulid-rails-sample

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