【Laravel】DBデータ挿入（save, create, insert）

### 追記 2024/7/19
[@pop-culture-studio様](https://qiita.com/pop-culture-studio)よりコメントでご享受いただき修正。

## 先に結論
<font color="lightgreen">``create()``</font>メソッドが記述量が少なく、複数代入から保護できる！
``fill()->save()``メソッドはコード量で難あり！（挿入ではなく、**更新**で使用）
``insert()``メソッドはセキュリティ面で難あり！（使わない）

``Illuminate\Database\Eloquent\Builder``と
``Illuminate\Database\Query\Builder``の違い

### この記事について

- Laravel初学者向け
- 今までDB挿入メソッドがごっちゃになっていた人

### 動作環境・使用するツールや言語
- OS バージョン
    　 Windows11 
- ツール
    　 VSCode
- フレームワーク
    　 Laravel8

### 前提として今回の簡単なマイグレーションファイルとモデル
```Laravel:create_tests_table.php
    public function up()
    {
        Schema::create('tests', function (Blueprint $table) {
            $table->id();
            $table->string('name', 255);
            $table->timestamps();
        });
    }
```
```Laravel:Test.php
    protected $guarded = [
        'id'
    ];

    protected $fillable = [
        'name'
    ];
```
- ``$guarded``
          Eloquentで書き換え不可能
- ``$fillable``
          Eloquentで書き換え可能

```Laravel:web.php
Route::get('/save', [TestController::class, 'save']);
Route::get('/create', [TestController::class, 'create']);
Route::get('/insert', [TestController::class, 'insert']);
```

## create()メソッド
```Laravel:TestController.php
public function create()
    {
        Test::create([
            'name' => 'CreateExample',
        ]);
    }
```
この状態で[/create]()にアクセスし、DBを確認すると、
id = 1,
name="CreateExample",　が挿入される。
次に``id``を指定し[/create]()にアクセスすると、、、
```Laravel:TestController.php
public function create()
    {
        Test::create([
            'id' => 10,
            'name' => 'CreateExample',
        ]);
    }
```
id = <font color="yellowgreen">2</font>,
name="CreateExample",　が挿入される。

``10``を指定しているのにもかからわず、<font color="yellowgreen">``2``</font>となる。

:::note 
``$guarded``のおかげで指定した``id``ではない値が自動で挿入される
:::

### save()メソッド

:::note warn
``create``メソッドと同じ挙動ですが、違いはコード量です
:::

```Laravel:TestController.php
public function save()
    {
        $test = new Test();
        $test->fill([
            'name' => 'TestExample',
        ]);
        $test->save();
    }
```
この状態で[/save]()にアクセスし、DBを確認すると、
id = 1,
name="CreateExample",　が挿入される。
次に``id``を指定し[/save]()にアクセスすると、、、
```Laravel:TestController.php
public function save()
    {
        $test = new Test();
        $test->fill([
            'name' => 'TestExample',
        ]);
        $test->save();
    }
```
id = <font color="yellowgreen">2</font>,
name="CreateExample",　が挿入される。

``10``を指定しているのにもかからわず、<font color="yellowgreen">``2``</font>となる。

:::note 
``$guarded``のおかげで指定した``id``ではない値が自動で挿入される
:::

### insert()メソッド

```Laravel:TestController.php
public function insert()
    {
        $test = new Test();
        $test::insert([
            'name' => 'InsertExample',
        ]);
    }
```
この状態で[/insert]()にアクセスし、DBを確認すると、
id = 1,
name="CreateExample",　が挿入される。
次に``id``を指定し[/insert]()にアクセスすると、、、
```Laravel:TestController.php
public function insert()
    {
        $test = new Test();
        $test::insert([
            'id' => 10,
            'name' => 'InsertExample',
        ]);
    }
```
id = <font color="yellowgreen">10</font>,
name="CreateExample",　が挿入される。

insertメソッドでは``id => 10``を指定すれば、<font color="yellowgreen">``10``</font>となる。
次にコードを変えずにもう一度[/insert]()にアクセスしてみると、、、
<font color="red">PRIMARY KEYが重複しています</font>というエラーが出てしまいます。

:::note alert
``insert``メソッドは``$guarded``と``$fillable``の制約を受けないため、思わぬバグを生む可能性がある
:::

## 追記　2024/7/19
下記コメントを頂戴し、修正。
>メソッドの違いではなく
Illuminate\Database\Eloquent\Builderと
Illuminate\Database\Query\Builderの違い。
Illuminate\Database\Eloquent\Modelから始まり、ModelにないメソッドはEloquent\Builderから探す、Eloquent\BuilderにもなければQuery\Builderから探す、という処理の移行がLaravel内で勝手に行われる。
ここを理解してないとEloquentを使ってるつもりで知らないうちにQuery Builderを使うことになる。
$fillableなどはEloquentの機能なのでQuery Builderに移ったら使えない。
慣れてる人はEloquentのメソッドしか使わずQuery Builderに処理が移らないように気を付けている。
新規作成はcreate()。更新はfill()->save()。
insert() update()は使わない。

[@pop-culture-studio様より](https://qiita.com/pop-culture-studio)