【初心者向け】Laravel5.3 で Laravel5.2のQuick Start にトライ！


#つくるもの

- タスクの追加
- タスクの削除
- タスクの一覧表示

ができるシンプルなtodoリストを作る。

##学べること

- ルーティング
- DBマイグレーション
- Eloquent ORM
- バリデーション
- Blade

##注意点

Laravel5.3のドキュメントにはQuick Startがなくなっているので、ページ右上のプルタブで **5.2** を選択。
（ **実際に使うverは5.3** ）

#アジェンダ

ドキュメントとは少し順番が前後するので注意。

1. インストール（Installation）
2. DB接続先の変更
3. ルート・画面の作り方（Routing / Building Layouts & Views）
4. マイグレーション（Prepping The Database > Database Migrations）
5. Eloquent ORM（Prepping The Database > Eloquent  Models）
6. タスクの追加（Adding Tasks）
7. タスクの削除（Deleting Tasks）
8. 完成済みソースコードのご案内

# 1. インストール

##Composerのインストール

LaravelはComposerでインストールするので、まずは[公式サイト](https://getcomposer.org/ "公式サイト")でComposerをインストール。
インストール済みの場合はスキップ。

##Laravelのインストール

ターミナルで次のコマンドを打てば「quickstart」という名前のプロジェクトが落ちてくる。

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

ターミナルでディレクトリ内に移動、Composerをインストールする。

```
cd ~/quickstart
composer install
```

サーバーを起動する。

```
php artisan serve
```

`http://localhost:8000/`にホーム画面が表示される。

# 2. DB接続先の変更

Homesteadを使ってもいいですが、さくっとつくりたいならsqliteで。

##.envファイルの接続先を変更

- 初期状態ではMySQLになっているので`.env`ファイル内の`DB_CONNECTION`を` sqlite`に書き換える
- `DB_HOST` `DB_PORT` `DB_DATABASE` `DB_USERNAME` `DB_PASSWORD`の前に`#`をつけてコメントアウト

##SQLiteファイルの作成

`database`ディレクトリ内に`database.sqlite`をつくる。

```
touch database/database.sqlite
```

# 3. ルート・画面の作り方

##ルート

アプリケーションのurlなどを書くところで、起点となるファイルは`routes/web.php`。

- タスクの一覧表示
- タスクの追加
- タスクの削除

の３つの操作についてのルートを書く。

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

Route::post('/task', function () {
    //
});

Route::delete('/task/{task}', function () {
    //
});
```

##画面（ビュー）

Laravelでは **Blade** というテンプレートエンジンが使える（`.php`も可）。
大きなメリットとして **子ビューが親ビューを継承できる、ヘッダーなどの共通部分を読み込める、などレイアウトの部品化が可能** である。

###Bladeの特徴

- 拡張子は`.blade.php`
- ビューの置き場所は`resources/views`
- データの埋め込みは`{{ $hoge }}`
- コメントの記法は`{{--コメント--}}`

###エラービューの作成（共通部品）

`resources/views/common/errors.blade.php`を作成し以下のコードを貼り付ける。

```php:errors.blade.php
@if (count($errors) > 0)
        <!-- Form Error List -->
<div class="alert alert-danger">
    <strong>Whoops! Something went wrong!</strong>

    <br><br>

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

###親ビューの作成

`resources/views/layouts/app.blade.php`を作り以下のコードを貼り付ける。

```app.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Laravel Quickstart - Basic</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://fonts.googleapis.com/css?family=Raleway:300,400,500,700" rel="stylesheet" type="text/css">
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" type="text/css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <style>
        body {
            font-family: 'Raleway';
            margin-top: 25px;
        }

        button .fa {
            margin-right: 6px;
        }

        .table-text div {
            padding-top: 6px;
        }
    </style>
    <script>
        $(function () {
            $('#task-name').focus();
        });
    </script>
</head>

<body>
<div class="container">
    <!-- Create Task Form... -->
    <nav class="navbar navbar-default">
        <div class="container-fluid">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>

                <a class="navbar-brand" href="#">Task List</a>
            </div>

            <div id="navbar" class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    &nbsp;
                </ul>
            </div>
        </div>
    </nav>
    
    <!-- Current Tasks -->
</div>

@yield('content')

</body>
</html>
```

###子ビューの作成

`resources/views/task.blade.php`に以下のコードを貼り付ける。

- `@extend`でレイアウトを継承する親ビューを指定
- `@include`で共通部品を読み込む
- `@section('content')`に親ビューの`@yield('content')`に挿入したい内容を記述


```php:task.blade.php
<!-- resources/views/tasks.blade.php -->

@extends('layouts.app')

@section('content')
<div class="container">
	<div class="panel-body">
	    <!-- Display Validation Errors -->
	    @include('common.errors')
	
	    <!-- New Task Form -->
	    <form action="{{ url('task') }}" method="POST" class="form-horizontal">
	        {{ csrf_field() }}
	
	        <!-- Task Name -->
	        <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>
	
	        <!-- Add Task Button -->
	        <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> Add Task
	                </button>
	            </div>
	        </div>
	    </form>
	</div>
	
	<!-- TODO: Current Tasks -->
</div>
@endsection
```

##画面を表示

`routes/web.php`に以下を追記。

```php:web.php
/** Show Task Dashboard **/
Route::get('/', function () {
	return view('task');
});
```

`http://localhost:8000`にアクセスすると`task.blade.php`の中身が表示される。
`task.blade.php`は親ビューである`app.blade.php`のレイアウトを継承している。

# 4. マイグレーション

##マイグレーションファイルの作成

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

とすると`database/migrations`の中に`☓☓☓☓_☓☓_☓☓_☓☓☓☓☓☓_create_tasks_table.php`ができる。
これは **マイグレーションファイル** というDBの設計図のようなものである。

##マイグレーションファイルの編集

`up()`にはDB作成時の命令、`down()`にはDB削除時の命令を書く。
デフォルトで`id`と`timestamps`が設定されているので、`name`という項目を追加することにする。

```php:☓☓☓☓_☓☓_☓☓_☓☓☓☓☓☓_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
```

これで`id` `name` `created_at` `updated_at`の４項目を持つテーブルがDBにできている。

###マイグレーションコマンド

```
php artisan migrate:install    // migrationsファイルだけ作成
php artisan migrate:rollback   // 直近のマイグレーションの巻き戻し
php artisan migrate:reset      // 全てのマイグレーションを巻き戻し
php artisan migrate:refresh   // migrate:reset後、マイグレーション実行
php artisan migrate:status     // マイグレーション実行状況の確認
```

[この記事](http://qiita.com/qiita-kurara/items/9a34f97a184a1d8c1c35 "この記事")とかおすすめ。

# 5. Eloquent ORM

Laravelには **Eloquent** というORMがあり、これを使うと簡単にDBのデータを取得できたりする。

##モデルの作成

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

`app`ディレクトリ内に`Task.php`ができる（使用方法は後述）

# 6. タスクの追加

##バリデーション

テーブルにつくった`name`という項目についてが10文字以下になるようにバリデーションを追加する。

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

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

    // Create The Task...
});
```

もしバリデーションに引っかかればエラーメッセージを表示し、`/`にリダイレクトする。

##タスクを追加する

- Eloquent Modelである`Task.php`を使ってタスクを作成
- `save`メソッドで保存
- 作成後は`/`にリダイレクト

```web.php
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('/');
});
```

##タスクを一覧表示する

`/`のルートを以下のように書き換える。

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

    return view('task', [
        'tasks' => $tasks // このデータがtask.blade.phpで使えるようになる
    ]);
});
```

###Eloquentを使ってDBのタスクを全て取得

```
$tasks = Task::orderBy('created_at', 'asc')->get();
```

`orderBy`は並び替えるメソッド、最後に`get( )` で呼び出すことでDBの値を全件取得。
第二引数の`asc`は大きくなっていく順（昇順）、`desc`にすれば小さくなっていく順（降順）になる。

###取得したタスクを一覧表示

`view`関数の第二引数に配列でデータを渡すとビューで使えるようになる。

```php:task.blade.php
<!-- resources/views/tasks.blade.php -->

@extends('layouts.app')

@section('content')
<div class="container">
	<!-- Create Task Form... -->
	
	<!-- Current Tasks -->
	@if (count($tasks) > 0)
	    <div class="panel panel-default">
	        <div class="panel-heading">
	            Current Tasks
	        </div>
	
	        <div class="panel-body">
	            <table class="table table-striped task-table">
	
	                <!-- Table Headings -->
	                <thead>
	                <tr>
	                    <th>Task</th>
	                    <th>&nbsp;</th>
	                </tr>
	                </thead>
	
	                <!-- Table Body -->
	                <tbody>
	                @foreach ($tasks as $task)
	                    <tr>
	                        <!-- Task Name -->
	                        <td class="table-text">
	                            <div>{{ $task->name }}</div>
	                        </td>
	                        <td>
	                            <!-- TODO: Delete Button -->
	                        </td>
	                    </tr>
	                @endforeach
	                </tbody>
	            </table>
	        </div>
	    </div>
	@endif
</div>
@endsection
```

ビュー側でデータを表示するときは`{{ $tasks }}`という形で表示できる。
`@if`で条件分岐、`@foreach`でループを回すことが可能。

# 7. タスクの削除

##ビューに削除ボタンを追加

以下を`task.blade.php`に追加。
削除ボタンがクリックされると`DELETE /task`リクエストが送られる仕組み。

```php:task.blade.php
<tr>
    <!-- Task Name -->
    <td class="table-text">
        <div>{{ $task->name }}</div>
    </td>

    <!-- Delete Button -->
    <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> Delete
            </button>
        </form>
    </td>
</tr>
```

##EloquentのdeleteメソッドでDBから削除する

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

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

# 8. 完成済みソースコードのご案内

GitHubに公開しています。
https://github.com/sshono1210/laravel5.3-BasicTaskList