初心者向けにLaravelのデータベースとModelあたりを解説

初心者向けにLaravelのデータベースとModelあたりを解説します。

## テーブル作ろう
さて、まずはテーブル作らんなん。 
昔は、手でポチポチカラムを作ったり、Excelにデーターベース情報を書いて、insert文を生成したりしていたが、もうそんなことはしなくていいんや！

Laravelには素晴らしいmigration（マイグレーション）機能というものがあります！

さて、まずはマイグレーションファイルを作ろう。

```
$ php artisan make:migration create_tests_table
```

※注意点としては、テーブル名は必ず複数形とすること。あとでModel作るときに困る。  
世の中の常識として、テーブルに保存するってことは、複数あるものを保存するんやから、複数形やろ！ってなってるんかもしれません。

これでマイグレーションファイルができました！

```php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateFruitsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('fruits', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('fruits');
    }
}
```

ちょっといじるか。。upメソッドの中変更しました。

```php

public function up()
{
    Schema::create('fruits', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name')->comment('お名前');
        $table->integer('price')->comment('お値段');
        $table->timestamps();
    });
}
```

では、このコマンドを打つべし！  

```
$ php artisan migrate
```

テーブル見るべし！（ちゃんと更新して）  
`fruits`テーブルできてますでしょ！？この時点でかなり感動。 
こちらのコマンドを打つと、upメソッドが走りますよ。

ちなみに、間違えて作った。やっぱやめたいというときは、

```
php artisan migrate:rollback
```
こちらのコマンドを打つと、downメソッドが走り、今回の場合だと`fruits`テーブルが削除されます。


このマイグレーション機能のすごいところは、テーブルの作成・削除だけでなく、更新もできるところ！ 
ユーザーテーブルに権限IDのカラムを追加したいとき

```php
<?php

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

class AddUserRoleColumn extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->integer('role_id')->comment('権限ID');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('role_id');
        });
    }
}
```

カラムの追加もできるし、renameもできるし、削除もできるし、優れものです。 
（ちゃんと前回実行したところまで覚えてくれていて、差分だけ実行してくれる）  
普段はそんなに困らないですが、すでに本番で稼働しているサーバーがあった場合などに修正を適用するときには、ミスが起きないので助かりますよ。


## では、Model作りますか
もはやModelがなんなのかは分からないので、説明は割愛します。

```
$ php artisan make:model Fruit
```

これでModelのファイルができます。  
私は、Modelsというディレクトリに置くことが多いので、こんな感じです。

```
$ php artisan make:model Models/Fruit
```

※Modelは単数系だ！！！  
あと、Laravelの標準に従って、大文字で始めよう。


できたのが以下のファイル

```php:app/Models/Fruit.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Fruit extends Model
{
    //
}
```

ちょっとプロパティ追加します

```php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Fruit extends Model
{
    protected $guarded = [
        'id'
    ];
}
```

`$guarded`というのは、プログラムから指定できない値（多分） 
`$guarded`と対になるもので、`$fillable`があります。 
`$fillable`は、プログラムから指定できる値を設定します。 
まぁ、`id`は自動増分ですからね。

ちなみに、`$guarded`か`$fillable`どちらかは指定必須です。 
指定がないとエラーで動きません。


## よし、保存しよう！の前に...
画面から保存できた方が分かりやすいわよね？ 
画面作ろう。ということは、ルーティングとControllerとviewか。。 
思ったより大掛かりやなぁ...  

### ルーティング

```php:routes/web.php
<?php
Route::get('fruit', 'FruitController@index')->name('fruit.index');
Route::post('fruit', 'FruitController@store')->name('fruit.store');
```

### view
```php:resources/views/fruit.blade.php
@extends('layouts.app')
@section('content')
<form action="{{ route('fruit.store') }}" method="post">
    <label>お名前</label>
    <input type="text" name="name">

    <label>お値段</label>
    <input type="text" name="price">

    <button type="submit">登録</button>
    @csrf
</form>
@endsection
```

### Controller
```
$ php artisan make:controller FruitController
```

このコマンドを打って、この内容に書き換えてください。

```php:app/Http/Controllers/FruitController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FruitController extends Controller
{
    public function index()
    {
        return view('fruit');
    }

    public function store()
    {
        //ここからメインなので、解説しながら！
    }
}
```

## やっと保存処理の解説できるぞー
Controllerを以下の通りに書き換えてください。

```php:app/Http/Controllers/FruitController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Models\Fruit;

class FruitController extends Controller
{
    public function index()
    {
        return view('fruit');
    }

    public function store(Request $request)
    {
        $fruitModel = new Fruit;

        $saveData = $request->all();

        $fruitModel->fill($saveData)->save();
    }
}
```

もう登録処理ができるので、画面の項目を入力して保存してもらってOKです。 
ただ、保存後は真っ白な画面に遷移してしまいますが...  

### 解説
`$request`には、画面から受け取ったデータが入っています。 
`$request->all()`で、以下の内容が取得できます。  

```php
array:4 [
  "name" => "オレンジ"
  "price" => "200"
  "_token" => "U1xrQ6sUkFgGM8HHXfMM7EHafvxRIJDWp8Wjq8PX"
  "_url" => "/fruit"
]
```

`fill`メソッドでモデルにデータをセットして、`save`メソッドで保存します。  

...さらっと書いてますけど、これすごく楽なんですよ！
別の書き方紹介しますね。  

```php
public function store(Request $request)
{
    $fruitModel = new Fruit;

    $fruitModel->name = $request['name'];
    $fruitModel->price = $request['price'];
    $fruitModel->save();
}
```

storeメソッドを書き換えました。え、行数変わってないって？ 
いやいや、画面の項目一つずつ指定してるので、項目が10個あったら10行書くハメになるんですよ...  
できるだけfillメソッド使うと、手間が省けますよ。  

ちなみに`created_at`と`updated_at`も自動で登録されます。

### ポイント
長いカラム名あるじゃないですか。例えば、`job_category_id`とか。  
カラム名は、もちろん単語の区切りはアンダーバーで切って、それに合わせてhtmlのinputのnameもアンダーバーで切って名前そろえておくといいですよ。  
（というか、そうしないと`$request->all()`と`fill`メソッドの恩恵が受けられません）  


## まとめ
もっと短い記事になるはずだったのに、長くなってしまいました。  
今回、割愛した箇所が多々ありますが、実際のシステムを作る時は、さらに作り込みが必要になります。 
（バリデーションとか、try catchとか）

登録・更新・削除、Laravelのおかげで幾分楽になったとはいえ、あと死ぬまで何回これを繰り返すんだろうってちょっと怖くなりますね。 
（すでにちょっと飽きてる...）