Edited at

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

More than 3 years have passed since last update.


概要

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


参考

http://stackoverflow.com/a/3049727

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