【Laravel5.8】Herokuデプロイ時のseederで Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint failsと言われる

こんな流れに数週間苦しまされてきました。

$ heroku run php artisan db:seed --class=BookTableSeeder -a アプリ名
In Connection.php line 664:
                                                                               
  SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update   
  a child row: a foreign key constraint fails (`heroku_d51f02321ecf3a9`.`book  
  s`, CONSTRAINT `books_category_id_foreign` FOREIGN KEY (`category_id`) REFE  
  RENCES `categories` (`id`) ON DELETE CASCADE) (SQL: insert into `books` (`a  
  uthor`, `category_id`, `isbn`, `photo_path`, `price`, `publisher`, `status`  
  , `title`) values (百田尚樹, 1, 978-4-06-217565-4, /images/novel.jpg, 1600,  
   相川書房, 1, 海賊と呼ばれた男 下), (国友隆二, 3, 4-89386-497-1, /images/bu  
  ssiness.jpg, 1500, アイ・ディ・ジー・ジャパン, 2, 京セラ・アメーバ方式), (   
  長本吉斉, 5, 4-7569-0056-9, /images/others.jpg, 1800, 大泉書店, 3, はじめて  
  のTOEIC))                                                                    
                                                                               

In Connection.php line 458:
                                                                               
  SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update   
  a child row: a foreign key constraint fails (`heroku_d51f02321ecf3a9`.`book  
  s`, CONSTRAINT `books_category_id_foreign` FOREIGN KEY (`category_id`) REFE  
  RENCES `categories` (`id`) ON DELETE CASCADE)          

一般的にはテーブルリレーションがうまくいっていない時にでるエラーなのですが、「ローカル開発環境ではseederはうまく入っているのに…」という状態でした。

原因

原因は、Herokuのテーブルに入るデータはmigrate refreshやdelete from テーブル名をしてもidが1からにならないということです。

MySQL Workbenchでレコードを確認してみたところ、親テーブルのseederが削除したレコードの次から連番で入っていました。

解決策

以下の記事が参考になりました。
本番環境での検証データをリセットしよう[Heroku] - Qiita


Herokuのメニュー > Data で該当のappを登録して、こんな画面が出たら
f:id:nekorokkekun:20190801190815p:plain

Settings > Reset Database…ボタン

でデータベースがリセットされます。

そのあとは再び

$ heroku run php artisan migrate
$heroku run php artisan db:seed --class=BookTableSeeder -a アプリ名 //親テーブル
$heroku run php artisan db:seed --class=BookTableSeeder -a アプリ名 //子テーブル

で素直にseederが成功してくれました。