####前提
rails 5.2 (開発開始時は5.1。途中で5.2にアップグレード)
アプリケーションをrails5.0で開発しはじめたあと、rails5.2にアップグレードした結果、
バージョン間でのカラムの扱いの違いによる影響がでた。
具体的にいうと、
テーブルのIDカラムのデフォルトの型が、以下の通り変更となっている。
rails 5.0 : integer
rails 5.2 : bigint
これにより、開発開始後にrailsバージョンを5.0から5.2にアップデートしたところ、新しいforeign_keyが貼れない状態となった。
####事象
新しいモデル「tag_group」作成
% rails g model tag_group
Running via Spring preloader in process 2449
Deprecation warning: Expected string default value for '--test-framework'; got false (boolean).
This will be rejected in the future unless you explicitly pass the options `check_default_type: false` or call `allow_incompatible_default_type!` in your code
You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.
Deprecation warning: Expected string default value for '--test-framework'; got false (boolean).
This will be rejected in the future unless you explicitly pass the options `check_default_type: false` or call `allow_incompatible_default_type!` in your code
You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.
invoke active_record
create db/migrate/20200327104342_create_tag_groups.rb
create app/models/tag_group.rb
migrationファイル作成
% rails g migration AddTagGroups_idToUsers
既存モデル「user」のカラム「user_id」が外部キーとなるよう、migrationファイルに追記
% rails db:migrate
== 20200327104342 CreateTagGroups: migrating ==================================
-- create_table(:tag_groups)
rails aborted!
StandardError: An error has occurred, all later migrations canceled:
Column `user_id` on table `tag_groups` does not match column `id` on `users`, which has type `int(11)`. To resolve this issue, change the type of the `user_id` column on `tag_groups` to be :integer. (For example `t.integer :user_id`).
Original message: Mysql2::Error: Cannot add foreign key constraint: CREATE TABLE `tag_groups` (`id` bigint NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` text, `user_id` bigint, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL, INDEX `index_tag_groups_on_user_id` (`user_id`), CONSTRAINT `fk_rails_373fd4568e`
FOREIGN KEY (`user_id`)
REFERENCES `users` (`id`)
)
/Users/Taiti/projects/memo-space/db/migrate/20200327104342_create_tag_groups.rb:3:in `change'
/Users/Taiti/projects/memo-space/bin/rails:9:in `require'
/Users/Taiti/projects/memo-space/bin/rails:9:in `<top (required)>'
/Users/Taiti/projects/memo-space/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Caused by:
ActiveRecord::MismatchedForeignKey: Column `user_id` on table `tag_groups` does not match column `id` on `users`, which has type `int(11)`. To resolve this issue, change the type of the `user_id` column on `tag_groups` to be :integer. (For example `t.integer :user_id`).
Original message: Mysql2::Error: Cannot add foreign key constraint: CREATE TABLE `tag_groups` (`id` bigint NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` text, `user_id` bigint, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL, INDEX `index_tag_groups_on_user_id` (`user_id`), CONSTRAINT `fk_rails_373fd4568e`
FOREIGN KEY (`user_id`)
REFERENCES `users` (`id`)
「モデル「tag_group」で、外部キーに設定するUserモデルのIDの型がinteger型になっていて合わないよ。」
「bigint型にすれば解決できるよ。」
####原因
rails5.0 のときに作られたUserモデルを作ったため、IDカラムの型がinteger型となっている。
rails5.2にアップグレードした後に作ったモデル「tag_group」で、foreign_keyを作成しようとする際、bigint型で作成しようとする。
その結果、型の不一致が起こりエラーとなる。
####解決方法
構築済みのモデルのIDカラムをbidint型で再作成する必要があるため、以下の方法を検討
①rails db:rollbackしてDBを再実装する。
→ 手間がかかるため、できれば他の方法が良い
②rails db:resetしてみた。
(rails 5.2にアップデート後に実行することで、バージョンのデフォルト型が反映されることを期待)
→ 変化なし
③rails db:migrate:reset してみた。
(rails 5.2にアップデート後に実行することで、バージョンのデフォルト型が反映されることを期待)
→ 変化なし
④全てのmigrationファイルについて、記載されたバージョンを修正後にrails db:migrate:resetしてみる
(migrationファイルに定義されたバージョンを発見したため)
修正前
class ChangeColumnToNotNull < ActiveRecord::Migration[5.0]
…
修正後
class ChangeColumnToNotNull < ActiveRecord::Migration[5.2]
…
% rails db:migrate:reset
→ 既存モデルのIDカラムがbigint型で再構築された。
db/schema.rb も修正されている。
db/schema.rbに記載されたIDカラムの型をbigintに変更してから「rails db:reset」しても対処可能か?