LoginSignup
3
2

More than 3 years have passed since last update.

rails5.2にアップデートしたら外部キーでマイグレーションが失敗するようになった

Last updated at Posted at 2019-04-25

概要

rails5.0からrails5.2にバージョンを上げた時にマイグレーションが失敗するようになったので,原因の調査と解決を行なった.

原因

出力されたエラーは以下で,エラーを読むと,usersテーブルのidをmicropostsテーブルのuser_idの外部キーとして設定することに失敗したことが分かりました.


ActiveRecord::StatementInvalid: Mysql2::Error: Referencing column 'user_id' and referenced column 'id' in foreign key constraint 'fk_rails_558c81314b' are incompatible.: ALTER TABLE `microposts` ADD CONSTRAINT `fk_rails_558c81314b`
FOREIGN KEY (`user_id`)
  REFERENCES `users` (`id`)

...
Caused by:
Mysql2::Error: Referencing column 'user_id' and referenced column 'id' in foreign key constraint 'fk_rails_558c81314b' are incompatible.

原因となっているusersテーブルとmicropostsテーブルのスキーマを調べたところ,userテーブルのidはbigint型,micropostsテーブルのuser_idはint型となっており,型が一致していませんでした.
これはrails5.1からテーブルのidカラムがbigintになったことによって起きたことでした.

mysql> show create table users \G;
*************************** 1. row ***************************
       Table: users
Create Table: CREATE TABLE `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  `password_digest` varchar(255) DEFAULT NULL,
  `remember_digest` varchar(255) DEFAULT NULL,
  `admin` tinyint(1) DEFAULT '0',
  `activation_digest` varchar(255) DEFAULT NULL,
  `activated` tinyint(1) DEFAULT '0',
  `activated_at` datetime DEFAULT NULL,
  `reset_digest` varchar(255) DEFAULT NULL,
  `reset_sent_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `index_users_on_email` (`email`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)


mysql> show create table microposts \G;
*************************** 1. row ***************************
       Table: microposts
Create Table: CREATE TABLE `microposts` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `content` text,
  `user_id` int(11) DEFAULT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  `picture` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_microposts_on_user_id_and_created_at` (`user_id`,`created_at`) USING BTREE,
  KEY `index_microposts_on_user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

解決策

今回は外部キーであるuser_idの型をbigintに変更することで対応しました.
具体的な対応としては,schema.rbを以下のように変更しました.

create_table "microposts", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    ...
    t.integer   "user_id"
    t.datetime "created_at",               null: false
    t.datetime "updated_at",               null: false
    ...
end



create_table "microposts", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    ...
    t.bigint   "user_id"
    t.datetime "created_at",               null: false
    t.datetime "updated_at",               null: false
    ...
end

この後,rails db:setupを実行することで,無事マイグレーションが成功するようになりました.

参考

こちらの記事を参考にさせていただきました.

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2