Railsのマイグレーションにおけるreferencesの使い方を探していませんか?
ぼくも業務でRailsの中間テーブルを作る際にreferences型を使ったんですが、null: falseは必要なのか、foreign_key: trueは必要なのか、など迷いますよね?
そこでこの記事ではreferencesの使い方や実装例を具体例つきで解説します。
最後まで読めば、referencesを上手に使いこなせるようになります。

この記事を書いているぼくは実務経験1年。独学で未経験から従業員300名以上の自社開発企業へ転職しました。実務ではVue.jsとRailsを毎日書いています。
references型の使い方
referencesのオプションとそれぞれのデフォルト値をまとめます。
| オプション | 説明 | デフォルト値 |
| :type | カラムのデータ型 | :bigint |
| :index | インデックスを付与するか | true |
| :foreign_key | 外部キーの制約 | false |
| :polymorphic | ポリモーフィックの付与 | false |
| :null | NULLを許容するか? | true |
インデックスこそデフォルトで付与してくれますが、外部キー制約はそのままでは付かない、とのことでした。
なので外部キー制約のついたカラムを作りたい場合は、マイグレーションファイル内でforeign_key: trueを書くのが適切です。
中間テーブルの実装例
# UserとPostの中間テーブルとしてBookmarkを作る(foreign_key: trueを使用)
class CreateBookmarks < ActiveRecord::Migration[6.1]
def change
create_table :bookmarks, comment: 'ブックマーク' do |t|
t.references :user, foreign_key: true
t.references :post, foreign_key: true
t.timestamps
end
end
endもしくは次のようにadd_foreign_keyを使って書いてもOKです。
# UserとPostの中間テーブルとしてBookmarkを作る(add_foreign_keyを使用)
class CreateBookmarks < ActiveRecord::Migration[6.1]
def change
create_table :bookmarks, comment: 'ブックマーク' do |t|
t.references :user
t.references :post
t.timestamps
end
# add_foreign_key :参照先テーブル, :参照元テーブル
add_foreign_key :bookmarks, user
add_foreign_key :bookmarks, post
end
endreferencesを使うとuser_idとpost_idにはインデックスが自動で貼られます。
なので必要に応じて、以下のようにuser_idとpost_idの複合インデックスだけ貼ればOKですね。
# UserとPostの中間テーブルとしてBookmarkを作る
class CreateBookmarks < ActiveRecord::Migration[6.1]
def change
create_table :bookmarks, comment: 'ブックマーク' do |t|
t.references :user, foreign_key: true
t.references :post, foreign_key: true
t.timestamps
end
#
add_index :bookmarks, [:user_id, :post_id], unique: true
end
endreferencesを使わない場合
referencesを使わないと中間テーブルが作れないわけではありません。
referencesを使わずに同じテーブルを作ろうとすると、次の記述になります。
# UserとPostの中間テーブルとしてBookmarkを作る(referencesを使わない)
class CreateBookmarks < ActiveRecord::Migration[6.1]
def change
create_table :bookmarks, comment: 'ブックマーク' do |t|
t.integer :user
t.integer :post
t.timestamps
end
# add_foreign_key :参照先テーブル, :参照元テーブル
add_foreign_key :bookmarks, :user
add_foreign_key :bookmarks, :post
add_index :bookmarks, [:user_id, :post_id], unique: true
end以下の2つが注意点です。
- referencesを使わない場合、カラムに
foreign_key: trueを記述しても外部キー制約にはならない。add_foreign_keyで外部キー制約をつける必要あり add_foreign_keyで外部キー制約をつけた場合、インデックスも自動で貼られるので、user_idとpost_idへadd_indexは不要
まとめ
今回は中間テーブルを作りたかったため、外部キーは必須となります。
最終的に以下のマイグレーションファイルになりました(名称は仮名)
# UserとPostの中間テーブルとしてBookmarkを作る
class CreateBookmarks < ActiveRecord::Migration[6.1]
def change
create_table :bookmarks, comment: 'ブックマーク' do |t|
t.references :user, null: false, foreign_key: true
t.references :post, null: false, foreign_key: true
t.timestamps
end
add_index :bookmarks, [:user_id, :post_id], unique: true
end
referencesを使うとデフォルトでインデックスは貼ってくれるが、それ以外の制約は自分で付与する必要がある、と理解できました。
referencesを使いこなせるようになると、マイグレーションファイルをとても効率的に書けるので、しっかりマスターしておきましょう。
また、以下の記事ではワンランク上のRailsエンジニアになりたいと考えている方向けにおすすめの技術書を紹介しています。
こちらの記事もぜひ読んでみてください。






コメント