Laravel5.6チュートリアル 基本のタスクリスト

Laravel入門者がLaravel5.1ドキュメントの[基本のタスクリスト](https://readouble.com/laravel/5.1/ja/quickstart.html)を5.6でやっていく。
大きく違うのはバリデーションくらいだが、全体的に名前空間やディレクトリ構成がちょいちょい変わってるので、元チュートリアル掲載分のソースはすべて書き出した。
著作権的に問題があるようなら修正or削除対応します。

# インストール

割愛。

# データベースの準備
## データベースマイグレーション

マイグレーションファイルを作成。

```bash
php artisan make:migration create_tasks_table --create=tasks
```

生成されたファイルを編集。

```php:database/migrations/XXXX_XX_XX_XXXXXX_create_tasks_table.php
<?php

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

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

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

テーブル生成。

```
php artisan migrate
```

## Eloquentモデル

EloquentはLaravelで定番のORM。
モデルを作る。

```bash
php artisan make:model Task
```

デフォルトではappディレクトリ直下に作られる。
Rails等使った経験があるとかなり気持ち悪く感じる。
`Models`ディレクトリを作ってその下にモデル配置とかもできるようだがチュートリアルなのでデフォルトのままで進める。

```php:app/Task.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    //
}
```

# Routing
## ルートのスタブを定義

ルーティング設定。
とりあえず中身が空のルーティングファンクションをざっと作る。

```php:routes/web.php
<?php

use App\Task;
use Illuminate\Http\Request;

/**
 * 全タスク表示
 */
Route::get('/', function () {
    //
});

/**
 * 新タスク追加
 */
Route::post('/task', function (Request $request) {
    //
});

/**
 * 既存タスク削除
 */
Route::delete('/task/{id}', function ($id) {
    //
});
```

## ビューの表示

`view`関数の引数にビュー名を書いて`return`するとビュー表示できる。

```php:routes/web.php
Route::get('/', function () {
    return view('tasks');
});
```

# レイアウトとビューの作成
## レイアウト定義

ビューを作っていく。
土台になる`app`ビューを作る。
こいつは`layouts`ディレクトリを作ってその中に入れる。

```html:resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Laravel Quickstart - Basic</title>

        <!-- CSSとJavaScript -->
    </head>

    <body>
        <div class="container">
            <nav class="navbar navbar-default">
                <!-- ナビバーの内容 -->
            </nav>
        </div>

        @yield('content')
    </body>
</html>
```

# 子ビューの定義

土台の`app`ビューの上に乗せる`task`ビューを作る。
blade記法`@extends`を用いることで継承する親ビューを指定できる。

```html:resources/views/tasks.blade.php
@extends('layouts.app')

@section('content')

    <!-- Bootstrapの定形コード… -->

    <div class="panel-body">
        <!-- バリデーションエラーの表示 -->
        @include('common.errors')

        <!-- 新タスクフォーム -->
        <form action="/task" method="POST" class="form-horizontal">
            {{ csrf_field() }}

            <!-- タスク名 -->
            <div class="form-group">
                <label for="task" class="col-sm-3 control-label">Task</label>

                <div class="col-sm-6">
                    <input type="text" name="name" id="task-name" class="form-control">
                </div>
            </div>

            <!-- タスク追加ボタン -->
            <div class="form-group">
                <div class="col-sm-offset-3 col-sm-6">
                    <button type="submit" class="btn btn-default">
                        <i class="fa fa-plus"></i> タスク追加
                    </button>
                </div>
            </div>
        </form>
    </div>

    <!-- TODO: 現在のタスク -->
@endsection
```

# タスク追加
## バリデーション

ここは完全に関数が変わったっぽい。
5.6のドキュメントを参照する。

https://readouble.com/laravel/5.6/ja/validation.html

```php:routes/web.php
/**
 * 新タスク追加
 */
Route::post('/task', function (Request $request) {
    $validator = $request->validate([
        'name' => 'required|max:255'
    ]);

    // タスク作成...
});
```

多分これで合ってるはず……
違ったら指摘下さい。

バリデーションを通らなかった場合に表示する`erros`ビューを作る。
commonsディレクトリを作ってその中に入れる。

```html
:resources/views/common/errors.blade.php
@if (count($errors) > 0)
    <!-- フォームのエラーリスト -->
    <div class="alert alert-danger">
        <strong>おや？何かがおかしいようです！</strong>

        <br><br>

        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
```

## タスク作成

バリデーションの項目で気づいたが、Laravelではルーティングファイルにガンガン処理を書いていける。
が、多分アンチパターンなので実践では処理はちゃんとコントローラーやモデルに書くようにした方が良さそう。

```php:routes:web.php
Route::post('/task', function (Request $request) {
    $request->validate([
        'name' => 'required|max:255'
    ]);

    $task = new Task;
    $task->name = $request->name;
    $task->save();

    return redirect('/');
});
```

## 既存タスクの表示

`view`関数の第2引数でビュー側に変数を渡せる。

```php:routes/web.php
Route::get('/', function () {
    $tasks = Task::orderBy('created_at', 'asc')->get();

    return view('tasks', [
        'tasks' => $tasks
    ]);
});
```

だいぶ完成が近づいてきた。

```html:resources/views/task.blade.php
@extends('layouts.app')

@section('content')
    <!-- タスクフォームの作成… -->

    <!-- 現在のタスク -->
    @if (count($tasks) > 0)
        <div class="panel panel-default">
            <div class="panel-heading">
                現在のタスク
            </div>

            <div class="panel-body">
                <table class="table table-striped task-table">

                    <!-- テーブルヘッダー -->
                    <thead>
                        <th>Task</th>
                        <th>&nbsp;</th>
                    </thead>

                    <!-- テーブルボディー -->
                    <tbody>
                        @foreach ($tasks as $task)
                            <tr>
                                <!-- タスク名 -->
                                <td class="table-text">
                                    <div>{{ $task->name }}</div>
                                </td>

                                <td>
                                    <!-- TODO: 削除ボタン -->
                                </td>
                            </tr>
                        @endforeach
                    </tbody>
                </table>
            </div>
        </div>
    @endif
@endsection
```

# タスク削除
## 削除ボタンの追加

```html:resources/views/task.blade.php
<tr>
    <!-- タスク名 -->
    <td class="table-text">
        <div>{{ $task->name }}</div>
    </td>

    <!-- 削除ボタン -->
    <td>
        <form action="/task/{{ $task->id }}" method="POST">
            {{ csrf_field() }}
            {{ method_field('DELETE') }}

            <button>タスク削除</button>
        </form>
    </td>
</tr>
```

## タスク削除

```php:routes/web.php
Route::delete('/task/{id}', function ($id) {
    Task::findOrFail($id)->delete();

    return redirect('/');
});
```

これで終わり。
Bootstrap適用は気が向いたら書き足します。

# 参考
https://readouble.com/laravel/5.1/ja/quickstart.html
https://readouble.com/laravel/5.6/ja/validation.html