Just do IT

思うは招く

【Rails】既存のテーブルにカラムを追加し、外部キーとして設定する

例1:references型を使わない

やりたいこと

  • User(親)モデルとReport(子)モデルを紐付けたい
  • Repors テーブル に user_id を外部キーとして追加したい

まず、カラムを追加する。

bin/rails g migration add_[新しいカラム名]_to_[テーブル名] [新しいカラム名]:[データ型]

今回の場合、reportsテーブルにuser_idを追加する。 親モデル名であるUserと、idをくっつけることでRailsが自動的に「UserモデルはReportモデルの親モデル」と認識してくれる。

bin/rails g migration add_user_id_to_reports user_id:integer

生成されたマイグレーションファイル

class AddUserIdToReports < ActiveRecord::Migration[6.0]
  def change
    add_column :reports, :user_id, :integer
  end
end

Userに追記

class User < ApplicationRecord
  has_many :reports, dependent: :destroy
end

Reportモデルに追記

class Report < ApplicationRecord
  belongs_to :user
end

確認する

しっかりとアソシエーションができているか確認する。

コンソールを起動。

rails c

適当なUserを取り出す。

user = User.find 3

そのuserに紐付いたreportsを作ってみる

user.reports.create title:"テストタイトル", body:"テストボディ"

表示させてみる。

user.reports.find 1

[["user_id", 3], ["id", 1], ["LIMIT", 1]]
=> #<Report id: 1, title: "テストタイトル", body: "テストボディ", created_at: "2020-03-13 01:23:07", updated_at: "2020-03-13 01:23:07", user_id: 3>

アソシエーションできているのがわかる。

例2:references型を使う

やりたいこと

  • User(親)モデルとPages(子)モデルを紐付けたい
  • Pages テーブルに user_id を外部キーとして追加したい
bin/rails g migration AddReferencesToPages

マイグレーションファイル

class AddReferencesToPages < ActiveRecord::Migration[6.0]
  def change
    add_reference :pages, :user, foreign_key: true
  end
end

ちなみにnull: falseをつけていたらマイグレーションが通らなかった。

なお、t.referencesadd_referenceを使うと自動でindexが作られる。

create_table 内での t.referencesやadd_reference を使うとdefaultでindexが作られます

Railsで外部キー制約のついたカラムを作る時のmigrationの書き方 - Qiita

参考