CakePHPに慣れた私がLaravel触ってみる

環境構築できた([環境構築編](http://qiita.com/ran/items/14053e3f3fb20ed7c38a))ので、いよいよ中身を触ってみます。
(普段、CakePHP(最近は3)を使ってるので、自然と軽く比較になってます。)

5.1が入ったと思ってたんですが5.2が入っていたようで、途中でうまくいかないところがあって悩みました…。
ちなみにバージョンは

```bash
$ php artisan --version
```

で確認できます。
5.2だと日本語のドキュメントがまだない…orz

参考：
[5.1基本のタスクリスト](http://readouble.com/laravel/5/1/ja/quickstart.html)
[5.2ドキュメント(英語)](https://laravel.com/docs/5.2)

# 設定

`config/app.php`が一番基本の設定ファイルのようです。
url, timezone, localeを変えてみました。

```php:config/app.php
'url' => 'http://homestead.app',
'timezone' => 'Asia/Tokyo',
'locale' => 'ja',
```

# 最初にデフォルトで画面に表示される『Laravel 5』はどこの何が出てるのか

CakePHPだとroutesに書くのはURLをどう展開するかぐらいだと思いますが、Laravelはもう少し色々(CakePHPだとコントローラーに書くようなことも)書けるようです。
静的ページとかだとコントローラー書かなくて良くていいですね。

デフォルトで以下のような記述があります。

```php:app/Http/routes.php
Route::get('/', function () {
    return view('welcome');
});
```

getで`/`にアクセスした時にwelcome viewを返す、ということのよう。
viewファイルは、`resources/views/welcome.blade.php`にあります。
これが出ていたのですね。
viewファイルはBladeというテンプレートエンジンが使えるようで、`.blade.php`という拡張子を付けることになってるみたいです。

# bakeみたいなartisan

CakePHPだとbakeで必要なファイルを生成したりしますが、Laravelではartisanというのでやるようです。

# schema管理

前述のartisanを使います。
migrationファイルは、`database/migrations`以下にあって、すでに`users`テーブルと`password_resets`テーブルのファイルがデフォルトで用意されています。

新しく`bookmarks`テーブルを作ってみましょう。

```bash
$ php artisan make:migration create_bookmarks_table --create=bookmarks
```

`database/migrations`の下に新しいファイルができました。
`id`と`timestamps`(created_atとupdate_atが追加される)の記述しかないので、`title`と`url`カラムを追加することにします。

```php:database/migrations/2015_12_22_032734_create_bookmarks_table.php
・・・
public function up()
{
    Schema::create('bookmarks', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->text('url');
        $table->timestamps();
    });
}
・・・
```

実行！

```bash
$ php artisan migrate
```

Homesteadで作られてるDBは、仮想マシンで

```bash

$ mysql -u homestead -psecret homestead
```

とすると確認できます。
migrationはCakePHPのmigrationと似た感じですね。

# モデル

モデルもartisanで作ります。

```bash
$ php artisan make:model Bookmark
```

テーブル名が複数形(bookmarks)でモデル名が単数形(Bookmark)で対応するあたりはCakePHPと同じ感じかな。
モデルのファイルは`app/Bookmark.php`にできています。
とりあえずこれはこのまま放置。

# Routing

さっきチラッと見た`routes.php`に、ブックマークの一覧と追加アクションのルートを設定します。
コントローラーを作らずに`routes.php`だけで書くこともできますが、せっかくなのでコントローラーを作ることにします。

```php:app/Http/routes.php
Route::group(['middleware' => ['web']], function () {
    Route::resource('bookmark', 'BookmarkController', ['only' => ['index', 'store']]);
});
```

色んな書き方ができるようですが、[RESTful Resource Controllers](https://laravel.com/docs/5.2/controllers#restful-resource-controllers)というのを使ってみました。

ちなみに最初、`Route::group`の外に書いてたらセッションが保存されないらしく、エラーが出まくってて挫折しそうになりました…。

# コントローラー

なんでもartisanします。

```bash
$ php artisan make:controller BookmarkController --resource
```

`app/Http/Controllers/BookmarkController.php` ができました。
上記routingで設定した、indexとstoreのとこだけとりあえず書きます。

```php:app/Http/Controllers/BookmarkController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Bookmark;

class BookmarkController extends Controller
{
    public function index()
    {
        $bookmarks = Bookmark::orderBy('created_at', 'desc')->get();
        return view('bookmark', [
            'bookmarks' => $bookmarks
        ]);
    }

    public function store(Request $request)
    {
        $this->validate($request, [
            'title' => 'required|max:255',
            'url' => 'required',
        ]);

        $bookmark = new Bookmark;
        $bookmark->title = $request->title;
        $bookmark->url = $request->url;
        $bookmark->save();
        return redirect('/bookmark');
    }
}
```

# ビュー

ビューは外側のレイアウト部分と中のコンテンツ部分に分かれるのはCakePHPと同じ感じ。
layoutsディレクトリはないので作ります。

```php:resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html lang="ja">
    <head>
        <title>Laravel テスト</title>
    </head>
    <body>
        @yield('content')
    </body>
</html>
```

contentの中身の`bookmark.blade.php`も作ります。
新規追加用のフォームと、一覧表示があるページにします。
コントローラーで渡した`$bookmarks`が渡ってきています。

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

@section('content')
    @include('common.errors')

    <!-- 新規追加フォーム -->
    <form action="/bookmark" method="POST">
        {{ csrf_field() }}
        <div>タイトル：<input type="text" name="title"></div>
        <div>URL：<input type="text" name="url"></div>
        <div><input type="submit" value="追加"></div>
    </form>

    <!-- 一覧表示 -->
    @if (count($bookmarks) > 0)
        <table class="table">
            <thead>
                <th>Title</th>
                <th>URL</th>
            </thead>
            <tbody>
                @foreach ($bookmarks as $bookmark)
                    <tr>
                        <td>{{ $bookmark->title }}</td>
                        <td>{{ $bookmark->url }}</td>
                    </tr>
                @endforeach
            </tbody>
        </table>
    @endif
@endsection
```

上記でincludeしている、validation errorがある場合のエラー表示用のビューも作ります。
`$errors`は勝手にセットされてるみたいです。

```php:resources/views/common/errors.blade.php
@if (count($errors) > 0)
    <div class="alert alert-danger">
        <strong>入力にエラーがあります</strong>
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
```

ブラウザで`http://homestead.app/bookmark`を開くと追加フォームが表示され、登録して一覧表示に出るようになりました！ :clap: 

# まとめ

まだよくわからないけど、まぁまぁ簡単に書けそうな感じがしました。
ディレクトリ構成が少しわかりにくいかも。
> Controller → app/Http/Controllers
> Model → app直下
> View → resources/views

そのうち使う機会あるかな〜？