Rails5.1以降のテーブルとRails5.0以前のテーブルを関連付ける方法

Rails5.0以前はPKのデフォルトがintegerだったけどRails5.1からはbigintに変更されてる。
その影響でRails5.0以前に作成したテーブルへRails5.1以降のテーブルからFKを貼ろうとすると型が違うので怒られる。

参考になった記事:Rails 5.1以前に作成されたテーブルにFK制約を張れない問題の解決策

下記は怒られたケースのサンプル

# 前提:user_groupsテーブルがrails5.0以前に作成されておりidはintegerとする。
class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.references :user_group,     null: false, index: true, comment: 'user_groups.id'
      t.string     :name,        null: false, comment: '氏名'
      t.string     :furigana,    null: false, comment: 'ふりがな'

      t.timestamps null: false
    end
  end
end

解決方法

参考リンクに書いてある通りなんだけど2通りの解決方法が考えられる。

  • 5.1以降のテーブルのFKの型をintegerに変更する。
  • 5.0以前に作成されたテーブルのPKの型をbigintに変更する。

状況によるけどrails5.0以前のテーブルは稼働中の状況が多そうなのでFKの型をintegerに指定する方法のほうが影響範囲が小さくなる傾向にある気がする。(システム刷新みたいな時にはPKの型を変更する方法を選択するのかな)

FKの型をintegerに変更する方法にも2種類あるけどreferencesを使ってtypeオプションで指定する方法がスッキリしてて個人的には好み。(下にtypeオプションを追加したサンプルを書いておく)
もう1種類はinteger型に指定してカラムを作った後、add_foreign_keyでFKを別途作成する方法。

class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      # FK作成時の型をtypeオプションを使ってinteger型に指定する
      t.references :user_group,     null: false, index: true, comment: 'user_groups.id', type: integer
      t.string     :name,        null: false, comment: '氏名'
      t.string     :furigana,    null: false, comment: 'ふりがな'

      t.timestamps null: false
    end
  end
end

DROPする際にrollback用の処理をスッキリ書く

テーブルを使う必要がなくなって削除する際にrollback出来るようにしておこうってときがある。
そんな時にシュッと書くためのtips。要はrequireして実行させる。

# 20170101132451_create_users.rb
# テーブル作成時のマイグレーションファイル
class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.references :user_group,     null: false, index: true, comment: 'user_groups.id'
      t.string     :name,        null: false, comment: '氏名'
      t.string     :furigana,    null: false, comment: 'ふりがな'

      t.timestamps null: false
    end
  end
end

悪い書き方

create時の内容をコピペ。typoの可能性もある。

# 20180101090509_drop_users.rb 
# テーブル削除時のマイグレーションファイル
class DropUsers < ActiveRecord::Migration[5.1]
  def up
    drop_table :users, if_exists: true
  end

  def down
    create_table :users do |t|
      t.references :user_group,     null: false, index: true, comment: 'user_groups.id'
      t.string     :name,        null: false, comment: '氏名'
      t.string     :furigana,    null: false, comment: 'ふりがな'

      t.timestamps null: false
    end
  end
end

良い書き方

create時のファイルをrequireして実行。typoの可能性はないしシンプル。

# 20180101090509_drop_users.rb
# テーブル削除時のマイグレーションファイル
require './db/migrate/20170101132451_create_users.rb'

class DropUsers < ActiveRecord::Migration[5.1]
  def up
    drop_table :users, if_exists: true
  end

  def down
    CreateUsers.new.change
  end
end
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.