始めに
忘れがちになるため、備忘録。
環境
Ruby 2.6.5
Rails 5.2.4.2
アソシエーション対象
投稿用のpostsテーブルと、ユーザーのusersテーブルを関連付け。
postsテーブルに外部キー制約を張ったuser_idカラムを追加する
カラム追加用のマイグレーションを作成
1.マイグレーション作成
$ rails g migration AddUserIdToPosts
2.マイグレーションファイルへの記述。foreign_key: trueを忘れずに記述すること。
db/migrate/[timestamps]_add_user_id_to_posts.rb
class AddUserIdToPosts < ActiveRecord::Migration[5.2]
def change
add_reference :posts, :user, foreign_key: true
end
end
※上手く外部キー制約が追加されない記述。
db/migrate/[timestamps]_add_user_id_to_posts.rb
class AddUserIdToPosts < ActiveRecord::Migration[5.2]
def change
add_reference :posts, :user, index: true
end
end
3.マイグレーションファイルの保存
$ rails db:migrate
何故、foreign_keyが必要なのか
Ruby on Rails APIより、
add_reference(table_name, ref_name, **options)
:foreign_key
Add an appropriate foreign key constraint. Defaults to false.Create a supplier_id column and appropriate foreign key
add_reference(:products, :supplier, foreign_key: true)
外部キー制約を張るためのforeign_keyはデフォルトではfalseになるため、ただ単にadd_referenceカラムを追加しただけでは外部キー制約は張られることがないとのこと。
つまり、「user.posts」のようにアソシエーションを利用してオブジェクトを取得しようとしても、外部キーが存在しないためエラーになるので注意が必要。
参考
Railsで外部キー制約のついたカラムを作る時のmigrationの書き方
後からreferencesカラムを追加しようとするとdb:migrateできない