Rails + mysql でテーブルのidのauto incrementをやめる


概要

Railsはふつう id という名前の自動採番のPKを作る(いわゆるサロゲートキー)が、そうではなく自然キーを利用したい場合にどうするか。

環境

Rails 5.0.0.1, MySQL 5.6, ruby 2.3.1,
mysql2 (gem) 0.4.4 で確認。

やり方

PK名自体は id で良いとすると、マイグレーションは以下のようになる。

class CreateHoge < ActiveRecord::Migration
  def change
    create_table :hoges, id: false do |t|
      t.column :id, 'int(11) PRIMARY KEY'
      t.integer :fuga

      t.timestamps null: false
    end
  end
end

t.column で生っぽく書けるのがポイント。

なお、 id という名前も変えたいのであれば、モデル側で self.primary_key = の設定が必要。

利用例

ある外部システムのIDと、内部のあるIDを、1対1に紐付けるだけのテーブルが必要になった。
標準では、 id hoge_id fuga_idの3カラムのテーブルになるが、リレーションもhoge_idやfuga_idでしかしないため、サロゲートキーとしてのidは全く役に立たないし紛らわしいだけなので、追い出した。

なるべく面倒を避ける為、 id という名前の自然キーにして、テーブル名に hoge を入れることで、hogeのidであると分かるようにした。

class CreateFugaHoge < ActiveRecord::Migration
  def change
    create_table :fuga_hoges, id: false do |t|
      t.column :id, 'int(11) PRIMARY KEY'
      t.integer :fuga_id, null: false # 内部テーブルであればreferencesでよい

      t.timestamps null: false

    end

    # fuga_idにunique indexはる

  end
end

参考

Rails3時代の回答だが、Rails5.0.0.1でも利用できていることを確認した。