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
end
references
を使うと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
end
referencesを使わない場合
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エンジニアになりたいと考えている方向けにおすすめの技術書を紹介しています。
こちらの記事もぜひ読んでみてください。
コメント