初めてのLaravel 5.1 : (21) View Partial

前回は記事の新規登録後に表示される記事一覧を修正しました。今回は、記事の編集画面を追加します。編集画面のフォームは新規登録画面のフォームとほぼ同じな為、Viewの Partial 機能を使って、フォームを共通部品化してみたいと思います。


Routing

ルートを追加します。

// app/Http/routes.php

Route::get('articles', 'ArticlesController@index');
Route::get('articles/create', 'ArticlesController@create');
Route::get('articles/{id}', 'ArticlesController@show');
Route::post('articles', 'ArticlesController@store');
Route::get('articles/{id}/edit', 'ArticlesController@edit');  // 追加
Route::patch('articles/{id}', 'ArticlesController@update');  // 追加

ArticlesController@editとArticlesController@updateへのルートを追加しました。updateの方はgetではなくpatchにしているので、お間違えなく。


Controller

ArticlesControllerにeditとupdateメソッドを追加します。

// app/Http/Controllers/ArticlesController.php

    public function edit($id) {
        $article = Article::findOrFail($id);

        return view('articles.edit', compact('article'));
    }

    public function update($id, ArticleRequest $request) {
        $article = Article::findOrFail($id);

        $article->update($request->all());

        return redirect(url('articles', [$article->id]));
    }
}

editは今までに学んで内容で作成でき、特に新しい要素はありません。

updateの方は、$idと$requestを引数で受け取っています。$requestは以前にやったFormRequestを継承したArticleRequestクラスを使用しています。FormRequestを使うことで、フォームの入力データのチェックとエラーがあった時の前画面へのリダイレクトを自動的に行なってくれます。updateメソッド内では $idに対応する記事を取得し、入力データで記事を updateし、記事表示画面にリダイレクトしています。

View

edit.blade.phpを作成します。以前に作成した create.blade.phpをコピーして修正します。

// resources/views/articles/edit.blade.php

@extends('layout')

@section('content')
    <h1>Edit: {{ $article->title }}</h1>

    <hr/>

    @if ($errors->any())
        <ul class="alert alert-danger">
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    @endif

    {!! Form::model($article, ['method' => 'PATCH', 'url' => ['articles', $article->id]]) !!}
    <div class="form-group">
        {!! Form::label('title', 'Title:') !!}
        {!! Form::text('title', null, ['class' => 'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('body', 'Body:') !!}
        {!! Form::textarea('body', null, ['class' => 'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('published_at', 'Publish On:') !!}
        {!! Form::input('date', 'published_at', $article->published_at->format('Y-m-d'), ['class' => 'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::submit('Edit Article', ['class' => 'btn btn-primary form-control']) !!}
    </div>
    {!! Form::close() !!}

@stop

create.blade.phpから修正したのは以下の4点になります。

  1. ページタイトルに記事のタイトルを表示
  2. Formタグの作成を From::open から Form::modelに変更。$articleの値をフォームに紐付ける為に Form::model を使用します。METHODに PATCHを指定し、urlへは$articleの idをパラメータとして引き渡します。
  3. published_at の入力項目の初期値を date(‘Y-m-d’)から $article->publieshed_atの値に変更。$article->published_at はArticleクラスで日付ミューテーターを指定している為、参照するとCarbonクラスのインスタンスが返ってきます。format()メソッドで文字列に変換して初期値とします。
  4. submit ボタンのタイトルを ‘Edit Article’ に変更

ここで、WWWブラウザを使って生成される formタグのソースを確認してみます。

...
<form method="POST" action="http://localhost:8000/articles/1" accept-charset="UTF-8">
    <input name="_method" type="hidden" value="PATCH">
...

WWWブラウザでは method は GETと POSTにしか対応していないため、Laravelでは hiddenを使って、PATCHメソッドをエミュレートしています。


View Partial

ここまでで、記事の編集機能は実装できましたが、新規記事作成フォームと、記事編集フォームで同じコードが重複しているで、Viewの Partial機能を使ってリファクタリングしてみます。

エラー表示の Partial化

form_errors.blade.php を作成します。

// resources/views/errors/form_errors.blade.php

@if ($errors->any())
    <ul class="alert alert-danger">
        @foreach ($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    </ul>
@endif

form_errors.blade.phpを使用するように、edit.blade.phpを修正します。

// resources/views/articles/edit.blade.php

@extends('layout')

@section('content')
    <h1>Edit: {!! $article->title !!}</h1>

    <hr/>

    @include('errors.form_errors')

    {!! Form::model($article, ['method' => 'PATCH', 'url' => ['articles', $article->id]]) !!}

        ...
        ...

    {!! Form::close() !!}

@stop

@includeを使って、form_errors.blade.php を参照します。form_errors.blade.phpは resources/views以下の errorsディレクトリに作成した為、’errors.form_errors’と指定します。

この様に、@include することを目的に切り出した bladeテンプレートファイルを Laravelでは Partialと呼んでいます。

Form部分の Partial化と、Partialへの値の渡し方

form.blade.php を作成します。

// resources/views/articles/form.blade.php

<div class="form-group">
    {!! Form::label('title', 'Title:') !!}
    {!! Form::text('title', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {!! Form::label('body', 'Body:') !!}
    {!! Form::textarea('body', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {!! Form::label('published_at', 'Publish On:') !!}
    {!! Form::input('date', 'published_at', $published_at, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
    {!! Form::submit($submitButton, ['class' => 'btn btn-primary form-control']) !!}
</div>

published_atの初期値は、$publishd_at 変数が渡されることを想定しています。また、submitボタンのタイトルも $submitButton変数が渡されることを想定しています。

form.blade.phpを使用するように、edit.blade.phpを修正します。

// resources/views/articles/edit.blade.php

@extends('layout')

@section('content')
    <h1>Edit: {!! $article->title !!}</h1>

    <hr/>

    @include('errors.form_errors')

    {!! Form::model($article, ['method' => 'PATCH', 'url' => ['articles', $article->id]]) !!}
        @include('articles.form', ['published_at' => $article->published_at->format('Y-m-d'), 'submitButton' => 'Edit Article'])
    {!! Form::close() !!}

@stop

@includeを使って、form.blade.phpを参照します。published_atと submitButtonの値を引き渡しています。


編集ボタンの追加

最後に、記事の表示画面に、編集ボタンを追加しておきます。

// resources/views/articles/show.blade.php

@extends('layout')

@section('content')
    <h1>{{ $article->title }}</h1>

    <hr/>

    <article>
        <div class="body">{{ $article->body }}</div>
    </article>

    <br/>

    {!! link_to(action('ArticlesController@edit', [$article->id]), '編集', ['class' => 'btn btn-primary']) !!}
@stop

link_toの第1引数にURLを指定するのですが、actionヘルパー関数を使ってURLを生成しました。


演習

create.blade.php も edit.blade.phpと同様に、partialを使うように修正してみてください。


まとめ

以下の事が出来るようになりました。

  • Form::modelを使って、データをフォームに紐付ける
  • Partial を使った、ビューの部品化
  • Partial への値の渡し方

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中