LoginSignup
0
0

uuid生成からルーティングでuuidをidとして使用するまでの方法を解説

Last updated at Posted at 2024-06-23

今回は実際のシステム開発の現場でuuidを使ったのでこれについてまとめました。

uuidとは?

uuid(Universally Unique Identifier)は、128ビットの一意の識別子として用いられます。

わかりやすくいうと、uuidは8-4-4-4-12の形式で表される32文字の16進数と4つのハイフンから構成されるため、1兆個のuuidを生成しても重複する確率は低いです。

そのため、大規模なシステムや分散システムでも、重複しない識別子として利用できます。主にデータベースやネットワーク上で一意の識別子として使用されます。

またuuidは16バイトのバイナリ形式で保存するため、文字列形式の36バイトに比べて大幅にストレージを節約できます。合わせてインデックスが小さくなり、検索が高速化されます。

uuidの設定

・ステップ1

まず、userモデルを作成し、「t.binary :uuid, limit: 16」というカラムを設定し、「add_index :users, :uuid, unique: true」という設定を加えます。

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.binary "uuid", limit: 16, null: false # 16バイトのバイナリ形式でUUIDを保存

      t.string :name
      t.string :email

      t.timestamps
    end

    add_index :users, :uuid, unique: true
  end
end

その後、rails db:migrateを行います。
ここでuuidをバイナリ形式で保存することで、インデックスのサイズが小さくなり、検索処理が高速になります。

インデックスのサイズが小さくなると、データベースがインデックスをメモリに保持できる可能性が高くなり、結果として検索クエリのパフォーマンスが向上します。また、バイナリ形式の比較は文字列形式よりも効率的に行えるため、検索処理自体も軽くなります。

・ステップ2

dbにデータを登録する際に、uuidを作成するモジュールとして設定をします。

module UuidGeneratable
  extend ActiveSupport::Concern

  included do
    before_create :generate_unique_uuid

    def generate_unique_uuid
      loop do
        self.uuid = self.class.binary_uuid( SecureRandom.uuid )
        break unless self.class.exists?( uuid: self.uuid )
      end
    end

    def self.binary_uuid( uuid_string )
      [uuid_string.delete( '-' )].pack( 'H*' )
    end

    def uuid_string
      self.class.string_uuid( uuid )
    end

    def self.string_uuid( binary_uuid )
      binary_uuid.unpack1( 'H*' ).scan( /.{8}|.{4}|.{4}|.{4}|.{12}/ ).join( '-' )
    end

    def self.find_by_uuid( uuid )
      params_uuid = [uuid.delete('-')].pack('H*')
      self.find_by( uuid: params_uuid ) 
    end
  end
end

※「loop do」の処理はなくてもいいかもしれません。

・ステップ3

modelファイルにモジュールをincludeする

class User < ApplicationRecord
  include UuidGeneratable
end

ルーティングでUUIDをIDとして使用する手順

先ほどの処理でuuidは登録できるようになりました。
今度はuuidをurlに含めて使用できるように設定をします。

・ステップ1

ルーティングを修正

  namespace :clients do
    root "dashboards#index"

    resources :companies, only: %i[ show ], param: :uuid # ここにURLでuuidをidにするよう設定
  end

・ステップ2

viewファイルにあるパスでidを渡していたところにuuidを設定
またここではdbから取得したインスタンスのuuidを直接使用するはできません。

理由としては、データベースから取得したUUIDデータはバイナリ形式で保存されており、そのままでは使用できません。そこで、uuid_string メソッドを使用してバイナリデータを文字列形式に変換し、読みやすい形で利用できるようにします。

そのためパスに渡す引数でメソッドを設定することでバイナリデータを文字列形式に変換します。

= link_to clients_company_path( @company.uuid_string ) 

これにより適切にルーティングでuuidをidとして使用できるようになります。

0
0
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
0
0