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
カラムを追加する際に挿入箇所を指定する方法
テーブルへカラムを追加する時、何も考えずにadd_column
すると最後のカラムの後ろに追加される。
関連する順番にカラムが並んでいると理解しやすいがバラバラだと判りにくい。。。
解決方法
add_column
にafter
オプションを追加すれば良い。
※DBがMySQLの場合に有効だけどPostgreSQLの場合は無効
# nameカラムの後ろにkanaカラムを追加する。
def change
add_column :users, :kana, :string, null: false, after: :name, comment: '名前のフリガナ'
end