Laravelで直接データベースをいじったら地獄を見た件

みなさん、こんにちは！

アプリを完成しましたが、データの削除の際に外部キーのエラーがあったので修正しようとしたところ、地獄を見たので愚痴らせてください。

### サービスについてはこちら
<a href="https://qiita.com/k-hayack884/items/e571138e8bf7f35f7502">laravel学んで2か月で自サービスを開発した話 Part1</a>

# 何が起きたか
![FireShot Capture 016 - フラワーギフト - flower-gift.herokuapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/9dbc3d42-68a5-eef5-44c1-dbfa7fa6c154.png)
以前、凍結されたぶりを削除しようとしたら、
![fireshot_capture_013_-_sqlstate_23000___integrity_constraint_violation__1451_cannot_delete_o__-_flower-gift.herokuapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/b8da2849-9e91-f6a1-afa6-84a1a078dcbf.png)

はい、外部キーの参照エラーです。
まあ、これは予想通りだったので、じゃけん直していこうね
![necchusyou_face_boy1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/111b7840-df62-7483-9e68-046c304ab7c1.png)

### 注意！ここからは私の試行錯誤が含まれます。真似すると地獄を見ますのでやめましょう！
## マイグレーションファイルを直接編集する
とりあえず、マイグレーションファイルを編集してphp artisan migrateすればええやろ！
```create_processed_products_table.php
     Schema::create('processed_products', function (Blueprint $table) {
            $table->id();
            $table->foreignId('admin_id')->constrained('admins');
            $table->foreignId('product_id')->constrained();
            $table->foreignId('product_id')
            ->onUpdate('cascade')
            ->onDelete('cascade')
            ->constrained('products');
            $table->boolean('result');
            $table->timestamps();
        });
```

cascadeを付けて変更すればええやん！それで、php artisan migrate　っと
![character_program_fat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/48806720-3418-ada9-a2ae-898eba91ad4d.png)
### nothing migration
![necchusyou_face_boy4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/685a929f-46cf-4b03-ec45-c525c073b70b.png)
### あ、あれっ？変更が反映されないぞ？
まあ、もしかしたら、変更がされているかもしれないし、削除ボタンと
![fireshot_capture_013_-_sqlstate_23000___integrity_constraint_violation__1451_cannot_delete_o__-_flower-gift.herokuapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/b8da2849-9e91-f6a1-afa6-84a1a078dcbf.png)

知ってた

## データベースを直接編集する
マイグレーションファイルが編集できないんだったら、データベースを直接編集すればええやん！
![スクリーンショット (63).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/aa839f36-4b8a-117b-5a67-1c2282b633e6.png)

ということで、データーベースの外部キーを**RESTRICT**から**CASCADE**に変更してと・・・
![necchusyou_face_boy1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/111b7840-df62-7483-9e68-046c304ab7c1.png)
### これなら大丈夫でしょ！
![fireshot_capture_013_-_sqlstate_23000___integrity_constraint_violation__1451_cannot_delete_o__-_flower-gift.herokuapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/b8da2849-9e91-f6a1-afa6-84a1a078dcbf.png)

３３－４

## さすがに知り合いに聞いてみた。
#### エンジニアさん「このエラーに関してどんなアプローチをしたんですか？」
![tehepero2_youngman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/2a5f15ff-fab1-a4a7-f303-cc3aa1f16cd4.png)

### マイグレーションファイルとデータベースの値を直接変更しちゃった

### エンジニアさん「今から緊急会議です。ZOOMつないでください。」
![bikkuri_me_tobideru_man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/5650e456-9048-2280-1182-0f7f33467ac9.png)
### ええええええええええええ！！

# 結局何がいけなかったのか
エンジニアさんと実際に話してみてわかったことが
- マイグレーションファイルは編集せずに、データベースに変更を加えるときは新しいマイグレーションファイルを作る
- データベースを直接いじらない
- データベースとマイグレーションの状況を合わせる
ということらしいので、さっそく助言もいただきながら修正してみた。

## マイグレーションファイルの作成

すでにあるマイグレーションファイルをいじるのはご法度なので、マイグレーションファイルを作成します
```processed_comments_table_drop_foreign.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class ProcessedCommentsTableDropForeign extends Migration
{

    public function up()
    {
        Schema::table('processed_comments', function (Blueprint $table) {
            $table->dropForeign('processed_comments_comment_id_foreign');
        });
    }

    public function down()
    {
        Schema::table('processed_comments', function (Blueprint $table) {
            $table->foreign('comment_id')->references('id')->on('comments');
        });

    }
}

```

このマイグレーションファイルを更新して既にある外部キーをドロップします

しかし、upメゾットだけだと、更新時にエラーが起きた時、**完全性が損なわれる**ので、**downメゾットにはupメゾットの逆**のことを書いていきます
この場合だと、外部キーをつける工程をdownメゾットに書きます
#### この逆のメゾットを考えるのが難しかった・・・

また、勝手にデータベースをいじってcascadeをつけてしまった分を補完するマイグレーションファイルを作ります
```change_foreignkey_restrict_to_cascade.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class ChangeForeignkeyRestrictToCascade extends Migration
{

    public function up()
    {

        Schema::table('processed_products', function (Blueprint $table) {
            $table->dropForeign('processed_products_product_id_foreign');
        });
        Schema::table('processed_comments', function (Blueprint $table) {
            $table->foreign('comment_id')->references('id')->on('comments')
            ->onUpdate('cascade')
            ->onDelete('cascade');
        });
        Schema::table('processed_products', function (Blueprint $table) {
            $table->foreign('product_id')->references('id')->on('products')
            ->onUpdate('cascade')
            ->onDelete('cascade');
        });
         
    }

    public function down()
    {
        Schema::table('processed_products', function (Blueprint $table) {
            $table->dropForeign('processed_products_product_id_foreign');
            $table->foreign('product_id')->references('id')->on('products');
        });
        Schema::table('processed_comments', function (Blueprint $table) {
            $table->dropForeign('processed_comments_comment_id_foreign');
        });
    }
}

```

この状態でphp artisan migrate していきます

## データベースにマイグレーションファイルを手動で追加
この状態で php artisan migrate:status でマイグレーションの状況を確認すると
![スクリーンショット (64).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/1b891fd4-83b7-19c1-7103-b537f3234098.png)

なぜNOになっているかというと、データベースにさっきの２つのマイグレーションファイルがないからです

そのため何をするかというと
![noname.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/efe2a5c7-e4b5-3cee-b83d-0eef0b9d7bb1.png)
### データベースをいじくってLaravelをだまします

どういうことかというと、

![スクリーンショット (65).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/c0a3cef1-6956-1cb5-ca5f-e4e637ddec57.png)

これで再び php artisan migrate:status　をすると２つのマイグレーションファイルがyesになります！

これでマイグレーションとLaravelの整合性が保たれました！
今度こそ凍結された商品を削除しましょう！

![スクリーンショット (66).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281946/8ad15435-851e-4d93-85ab-bf0cc6448ca6.png)
### やったぜ
# 終わりに
マイグレーションは一方通行だから、絶対に編集しちゃだめだぞ！
また、データベースも直接いじらず、マイグレーションファイルから指令を出しましょう！