箱のプログラミング日記。

渋谷の自社開発企業でRails書いてます。

referencesのカラムを後から追加・削除【Rails】

f:id:y_hakoiri:20191102121618j:plain

references型のカラムを後から追加したり削除したりしたい時にちょっとつまづいた話。

まずモデルの説明から

今回はuserモデルとgroupモデルがあり、中間テーブルはgroup_user。

あるグループを作成する時に複数userを選択しますが、 groupsテーブルにはグループ名やidなどが入り、 所属するメンバーは中間テーブルであるgroup_userを参照します。

追加したい時

最初に中間テーブルを作った時にuser_idのカラムを作り忘れて、後から追加する場合を想定

まず、こちらの記事を参考に以下のようにやってみました

Railsの外部キー制約とreference型について - Qiita

class AddUserIdToGroupUsers < ActiveRecord::Migration[5.1]
  def change
    add_reference :group_user, :user, foreign_key: true
  end
end

するとこんなエラーが。

ActiveRecord::StatementInvalid: Mysql2::Error: Table 'hoge_app.group_user' doesn't exist: ALTER TABLE group_user ADD user_id bigint

何だろう...ググって色々試してみたけどうまくいかず。

そこで、発生してるエラーは違ったんだけど、まさに少し前につまづいた時のこちらの記事と同じようにやってみた

カラムにreferencesの指定ができない【MySQL文法エラー】 - 箱のプログラミング日記。

(自分の記事をリンクで貼るの初めてだ。。ちょっと感動w)

class AddUserIdToGroupUsers < ActiveRecord::Migration[5.1]
  def change
    change_table :group_users do |t|
      t.references :user, foreign_key: true
    end
  end
end

すると、無事成功〜

(この記事結構前に書いたんですが、記事中で言ってる「この文法じゃないとダメっぽい」みたいなのは多分違う気がする。。すみません)

削除したい時

同じくgroup_usersテーブルからuser_idを削除したい場合

削除はこちらの記事を参考にしました

Railsのmigrationでreferencesの張られたカラムを削除する - Qiita

class RemoveUserIdFromGroupUsers < ActiveRecord::Migration[5.1]
  def change
    remove_foreign_key :group_users, :users
    remove_reference :group_users, :user, index: true
  end
end

こちらも無事成功。

まとめ

referencesのカラムを後から追加・削除したい時は一筋縄ではいかないので、少し工夫が必要ですね。

railsのマイグレーション関係はこの辺が少し不便な気がする。 お作法通りにマイグレーションファイルを作っても、結局ファイルの中身を少し変えてからマイグレートしなきゃいけなかったり。

referencesと外部キー制約を少し混同しているというか、厳密な違いみたいなものを説明できないので、きちんと勉強しておこう。。

.