PHP
laravel

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

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

インストール

割愛。

データベースの準備

データベースマイグレーション

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

php artisan make:migration create_tasks_table --create=tasks

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

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。
モデルを作る。

php artisan make:model Task

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

app/Task.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    //
}

Routing

ルートのスタブを定義

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

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するとビュー表示できる。

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

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

レイアウト定義

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

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を用いることで継承する親ビューを指定できる。

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

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

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

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

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

: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ではルーティングファイルにガンガン処理を書いていける。
が、多分アンチパターンなので実践では処理はちゃんとコントローラーやモデルに書くようにした方が良さそう。

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

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

    return redirect('/');
});

既存タスクの表示

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

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

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

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

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

タスク削除

削除ボタンの追加

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>

タスク削除

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