Laravel 5.2 基本のタスクリスト

イントロダクション

このクイックスタートガイドではデータベースマイグレーション、Eloqunet ORM、ルーティング、バリデーション、ビュー、Bladeテンプレートといった、Laravelフレームワークの基本を紹介します。Laravelフレームワークや一般的なPHPフレームワークに全く触れたことのない初心者の方にとって、よい入門となるでしょう。既にLaravelや他のフレームワークを使用しているのでしたら、より上級者向けに書かれたもう一つのクイックスタートが適しています。

Laravelの持つ機能の基本的な部分を試せるように、完了したいタスク全てを管理できるシンプルなタスクリストを構築してみます。言い換えれば、典型的なToDoリストのサンプルです。このプロジェクトの最終の完全なソースコードはGitHubから取得可能です。

インストール

Laravelのインストール

もちろん、最初にLararavelフレームワークを真新しくインストールする必要があります。Homestead仮想マシーンか、フレームワークを実行するために選択したローカルのPHP環境を使用します。ローカル環境が整ったら、Composerを使用しLaravelフレームワークをインストールできます。

composer create-project laravel/laravel quickstart --prefer-dist

クイックスタートのインストール(任意)

このクイックスタートの残りの部分をただ読み進めることもできますが、ソースコードをダウンロードしてローカルマシーンで実行したい場合は、Gitリポジトリーをクローンし、依存パッケージをインストールします。

git clone https://github.com/laravel/quickstart-basic quickstart
cd quickstart
composer install
php artisan migrate

ローカル開発環境の構築についてのドキュメントは、Homesteadインストールのドキュメントを参照してください。

データベースの準備

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

最初に全タスクを保持しておくためのデータベーステーブルを定義する、マイグレーション(migration:移行)を使ってみましょう。Laravelのデータベースマイグレーションはスラスラ書ける記述的なPHPコードを用いて、データベーステーブルの構造を定義し修正するための簡単な方法を提供しています。チームメンバーへ個別で用意しているデータベースのコピーへカラムを各自自分で追加するように伝える代わりに、あなたがソース管理にPushしたマイグレーションを実行してもらえます。

では、全タスクを保持するデータベーステーブルを構築しましょう。Artisan CLIは様々なクラスの生成に利用でき、Laravelプロジェクトを構築するためにたくさんタイプする手間を省いてくれます。今回はtasksテーブルのために、新しいデータベースマイグレーションをmake:migrationコマンドを使って生成します。

php artisan make:migration create_tasks_table --create=tasks

マイグレーションはプロジェクトのdatabase/migrationsディレクトリの中に設置されます。お分かりでしょうが、make:maigrationコマンドは、マイグレーションファイルへ自動増分IDとタイムスタンプの追加を始めに定義しています。このファイルを編集し、タスクの名前を保存するstringカラムを追加しましょう。

<?php

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

class CreateTasksTable extends Migration
{
    /**
     * マイグレーション実行
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * マイグレーション巻き戻し
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('tasks');
    }
}

マイグレーションを実行するには、migrate Artisanコマンドを使います。Homesteadを使っている場合、ホストからは直接データベースへ接続できないため、このコマンドは仮想マシーンで実行してください。

php artisan migrate

このコマンドは全データベーステーブルを生成します。お好きなクライアントを使用し、データベーステーブルを調べてもらえば、マイグレーションで定義したカラムを含んだ新しいtasksテーブルを見つけることができるでしょう。次に、タスクを表すEloquent ORMモデルを定義しましょう!

Eloquentモデル

EloquentはLaravelのデフォルトORM(object-relational mapper)です。Eloquentは明確に定義された「モデル」を用いることで、苦労せずにデータベースへのデータ保存/取得を行わせてくれます。通常各Eloquentモデルは、一つのデータベーステーブルに対応します。

では、作ったばかりのtasksデータベーステーブルに対応するTaskモデルを定義してみましょう。このモデルを生成するために、再度Artisanコマンドを使用します。この場合はmake:modelコマンドを使用します。

php artisan make:model Task

このモデルはアプリケーションのappディレクトリに設置されます。デフォルトではこのクラスは空です。データベーステーブルはモデルの複数形の名前だと想定されているため、Eloquentモデルがどのテーブルに対応するかを明確に宣言する必要はありません。ですから、この場合Taskモデルはtasksデータベーステーブルと対応していると想定しています。空のモデルは次のようになっています。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    //
}

アプリケーションにルートを追加してから、Eloquentモデルについて更に学びましょう。もちろん、ご自由にEloquentの完全なドキュメントを読んで、更に情報を学んでもかまいません。

ルート定義

ルートのスタブを定義

次に、アプリケーションにいくつかルートを追加しましょう。ルートはユーザがページにアクセスするために指定するURLを実行するコントローラーか無名関数を指定するために使用します。Laravelの全ルートはデフォルトで、新しいプロジェクトに必ず含まれているapp/Http/routes.phpファイルの中で定義します。

このアプリケーションでは、最低3つのルートが必要になることがわかっています。全タスクをリスト表示するルート、新しいタスクを追加するルート、既存のタスクを削除するルートです。では、app/Http/routes.phpファイルでこれらのルートを全部スタブ(空の代用コード)で定義しましょう。

<?php

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

/**
 * タスクダッシュボード表示
 */
Route::get('/', function () {
    //
});

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

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

注意: インストールしたLaravelに、webミドルウェアグループの中でデフォルトルートファイルを読み込んでいるRouteServiceProviderが含まれていれば、routes.phpファイルへグループを追加する必要はありません。

ビューの表示

次に/ルートを完成させましょう。このルートでは、新しいタスクを追加するフォームを含み、同時に現在の全タスクをリストするHTMLテンプレートを表示しましょう。

Laravelの全HTMLテンプレートはresources/viewsディレクトリに設置されます。ルートからこれらのテンプレートの一つを返すためにviewヘルパが使えます。

Route::get('/', function () {
    return view('tasks');
});

view関数に渡したtasksは、resources/views/tasks.blade.phpテンプレートに対応するビューオブジェクトインスタンを生成します。もちろん、このビューは実際に定義する必要がありますので、早速とりかかりましょう!

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

このアプリケーションは新しいタスクを追加するためのフォームを含み、同時に現在のタスクをリストするビューを一つだけ持ちます。ビューを想像するために役立つように、基本的なBootstrapのCSSスタイルを適用した、最終段階のアプリケーションのスナップショットをご覧ください。

Application Image

レイアウト定義

ほとんど全てのアプリケーションでは同じレイアウトをページに渡り共有します。たとえばこのアプリケーションは全ページ(一つ以上のページが存在する場合)で表示する、典型的なトップナビバーがあります。LaravelはBladeテンプレートを使い、こうしたページ間共通のフューチャーを簡単に共有できるようになっています。

前に説明したように、Laravelの全ビューはresources/viewsに設置されます。ですから新しいレイアウトビューもresources/views/layouts/app.blade.phpとして定義します。.blade.php拡張子はビューを表示するときにBladeテンプレートエンジンを使用することをフレームワークへ指示します。もちろん、Laravelでも普通のPHPテンプレートが使用できます。しかし、Bladeなら簡潔できれいなテンプレートを書くための便利なショートカットが利用できます。

app.blade.phpビューは以下のような構成になるでしょう。

<!-- 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>

レイアウトの@yield('content')の部分に注目です。これはレイアウトを拡張する全部の子ページが、自身のコンテンツを親へ注入できる場所を指定するための特別なBladeディレクティブ(指定子)です。次に、このレイアウトを使用しメインコンテンツを表示する、子のビューを定義しましょう。

子ビューの定義

次に、新しいタスクを作成するためのフォームと、存在する全タスクを同時に表示するビューを定義する必要があります。resources/views/tasks.blade.phpを定義しましょう。

Bootstrap CSSの定形コードを省いて、重要な部分に焦点を当てましょう。完全なソースコードはGitHubからダウンロードできることは覚えておいてください。

<!-- resources/views/tasks.blade.php -->

@extends('layouts.app')

@section('content')

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

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

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

            <!-- タスク名 -->
            <div class="form-group">
                <label for="task" class="col-sm-3 control-label">タスク</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

簡単な説明

先に進む前に、このテンプレートについて多少説明しましょう。最初に@extendsディレクティブにより、resources/views/layouts/app.blade.phpに定義したレイアウトを使用することをBladeに指示しています。@section('content')から@endsectionの間のコンテンツが、app.blade.phpレイアウトの中の@yield('content')ディレクティブの場所に挿入されます。

@include('common.errors')ディレクティブはresources/views/common/errors.blade.phpに設置されているテンプレートをロードします。このテンプレートはまだ定義していませんが、すぐに行います。

これでアプリケーションの基本レイアウトとビューが定義できました。このビューフォームを/ルートで実行することを思い出してください。

Route::get('/', function () {
    return view('tasks');
});

次に、フォーム入力を処理し、データベースに新しいタスクを追加するPOST /taskルートのコードを追加しましょう。

タスク追加

バリデーション

これでビューにフォームが用意できましたので、フォームの入力の正当性を確認し(バリデーション)、新しいタスクを作成するPOST /taskルートのコードをapp/Http/routes.phpへ追加しましょう。最初に、入力のバリデーションです。

このフォームでは、nameフィールドの入力が必須で、内容が255文字以下であることを確認しましょう。バリデーションに失敗したら、ユーザーを/のURLへリダイレクトし、同時に以前の入力とエラーをセッションへフラッシュデータとして保存します。フラッシュデータとしてセッションに入力を保存することで、バリデーションエラー時にユーザの入力を再表示できるようになります。

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

    if ($validator->fails()) {
        return redirect('/')
            ->withInput()
            ->withErrors($validator);
    }

    // タスク作成処理…
});

$errors変数

一休みして、この例の->withErrors($validator)の部分について解説しましょう。->withErrors($validator)の呼び出しは、指定されたバリデター(validator)インスタンスのエラーをフラッシュデータとしてセッションへ保存し、ビューの中で$errors変数としてアクセスできるようにしてくれます。

フォームのバリデーションエラーを表示するために@include('common.errors')ディレクティブをビューで使用したことを思い出してください。common.errorsによりバリデーションエラーを同じ形式で、全ページに渡り簡単に表示できるようにしています。このビューの内容を定義しましょう。

<!-- resources/views/common/errors.blade.php -->

@if (count($errors) > 0)
    <!-- Form Error List -->
    <div class="alert alert-danger">
        <strong>おや?何かがおかしいようです!</strong>

        <br><br>

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

注意: $errors変数は全てのLaravelビューの中で参照できます。バリデーションエラーが存在しない場合は、ViewErrorBagの空のインスタンスです。

タスク作成

これで入力のバリデーションは処理できました。新しいタスクを実際に作成するためにルート処理の定義を続けましょう。新しくタスクを生成したら、ユーザを/のURLへリダイレクトします。タスクを作成するには、新しいEloquentモデルに対しプロパティーを生成し、値を設定した後に、saveメソッドを使用します。

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

    if ($validator->fails()) {
        return redirect('/')
            ->withInput()
            ->withErrors($validator);
    }

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

    return redirect('/');
});

いいですね!これでタスクを作成できるようになりました。次に存在する全タスクをリストするビューを追加していきましょう。

既存タスクの表示

最初に、/ルートを編集し、既存の全タスクをビューに渡しましょう。view関数は第2引数に、ビューで使用するデータを配列で受け付けます。配列のキーはビューの中で変数となります。

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

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

データを渡したら、tasks.blade.phpビューの中でタスクを反復処理し、テーブルとして表示します。とても早く通常のPHPコードにコンパイルできる@foreach Blade構造文で簡単にループが記述できます。

@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

タスクアプリケーションは、もうほとんど完成です。しかし、終了した既存タスクを削除する手段がありません。次に実装しましょう。

タスク削除

削除ボタンの追加

コード中、削除ボタンを設置する場所に"TODO"を残してあります。では、tasks.blade.phpビューのタスクリストの各行に、削除ボタンを追加しましょう。小さなボタンひとつのフォームをリストの各タスクごとに作成します。ボタンがクリックされると、DELETE /taskリクエストがアプリケーションに送信されます。

<tr>
    <!-- タスク名 -->
    <td class="table-text">
        <div>{{ $task->name }}</div>
    </td>

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

            <button type="submit" class="btn btn-danger">
                <i class="fa fa-trash"></i> 削除
            </button>
        </form>
    </td>
</tr>

見せかけのメソッドの説明

削除ボタンフォームのmethodPOSTを使用しているのにかかわらず、定義しているルートはRoute::deleteである点に注目です。HTMLフォームはGETPOST HTTP動詞のみを許しています。そのため、フォームのDELETEリクエストを見せかける手段が必要になります。

フォームの中でmethod_field('DELETE')関数の結果を出力することにより、DELETEリクエストへ見せかけることができます。Laravelはこれを認識し、実際のHTTPリクエストメソッドをオーバーライドします。生成されるフィールドは次の内容です。

<input type="hidden" name="_method" value="DELETE">

タスク削除

最後に、指定したタスクを実際に削除するロジックをルートへ追加しましょう。{task}ルートパラメータに対応するTaskモデルを自動的に取得するため、暗黙のモデル結合が使えます。

ルートのコールバックの中で、レコードを削除するためにdeleteメソッドを使いましょう。レコードが削除された後は、ユーザを/ URLへリダイレクトします。

Route::delete('/task/{task}', function (Task $task) {
    $task->delete();

    return redirect('/');
});

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる