速習Larave3(その7)、更新処理No.2
Tags : Laravel3
チュートリアルの更新処理編。前記事からの続きです。
まず表示です。$data
に表示内容をセットし、ビューに渡します。
Tips!! 表示内容を渡すには、ビューを経由する方法の他、フォームの入力をInput::replaceメソッドで書き換えるという手法も取れます。研究してみてください。
$data
に配列で出力内容を受けています。今回は配列の要素をばらしてビューに渡していますが、まとめて渡してビューでキーを指定するのが好きな方もいるでしょう。お好みで通常の変数で受けてもスタンダードクラスのインスタンスで受けても、なんでも構いません。わかりやすいように書きましょう。
この$data
に状況に合わせて出力内容をセットするロジックを考えましょう。
- 初めてページを表示する場合は
- IDが指定されていれば更新処理なので、該当する記事を表示する
- IDが指定されていなければ新規の追加処理なので、空欄で表示する
- フォームからリダイレクトされた場合は、フォームに入力された内容を表示する
こうして分けて考えれば簡単ですね。それぞれは数ステップのコードで実現できます。
IDが指定されているかは簡単に判断できます。if文一つです。
ちょっと頭をひねるのは初めてページを表示する場合と、フォームからリダイレクトされてきた場合の判断です。何で判断しましょうか。
実はロジックで判断するのではなく、GETの処理を2つのルートに分けたほうが、明確で単純になります。最初のルートではデーターの取得をさせ、2番めのルートへリダイレクトさせます。その2番めのルートでフォームの表示を行います。フォームの送信内容を処理するPOSTの処理で、エラー時など同じ内容を表示させる場合は2番めのルート、全く新しいアクセスとして取り扱ってもらいたい場合は最初のルートと分けます。ルートを分ければ、ロジックで判断する必要はありません。
しかし、ルートが分かれる、つまり同じ処理に対するURIが分かれるのは好みではないため、この方法を取りませんでした。
これまで、このチュートリアルでは、フォーム表示にGETを、フォームの処理はPOSTを指定しました。これはブラウザから普通にアクセスする場合はGETメソッドですし、フォームを送信する場合はPOSTになりますから、それに一致しています。自然ですね。
POSTでフォーム内容を処理した後は、適当なページにリダイレクトします。今回のコードでは3つあります。
- エラー発生時に、メッセージ、入力内容とともにリダイレクト
- 新規追加後にIDを付けずにリダイレクト
- 更新時にID付きのURIへ入力内容とともにリダイレクト
入力内容と共にリダイレクトされるというのは、with()を使い、セッションの中にフラッシュデーターとして保存され、渡されるという事です。なぜ渡してやるかというと、その内容を表示してもらいたいからです。
つまり、ページで入力された項目のフラッシュデーターが存在すれば、その場合はそのデーターをそのまま表示しする場面です。逆に存在しないのは、新しくアクセスした状況として取り扱ってもらいたい場合です。このセッションデーターの有り無しで判断すれば、上手く動作できそうです。with_input()を使った場合、入力項目はたとえ未入力の状態であっても、セッションには空文字の値のアイテムとして保存されます。
このフラッシュデーターで判断する方法は、適用性があります。例えば新規で追加した後、このコードでは続けて新しく記事を追加できるようにID無しURIへダイレクトし、かつ入力データーを渡していません。ですからGETの処理ではフラッシュデーターが存在しませんし、IDも指定されていませんから、新規扱いとなり空欄で表示されます。
もしこれを「今作成した記事を表示させ、確認する仕様にしたい。変更点があればすぐに修正できるから」というように変更する場合、今度は新しく追加保存したばかりのレコードのIDを取得し、そのIDでURIへリダイレクト、その際にwith_input()
で入力を渡してやることで、入力データー=追加されたデーターを再表示できます。
つまり、フラッシュデーターを渡すか渡さないかで、GETのロジックに初期処理扱いをさせるか、それとも渡したデーターを表示させるか、リダイレクト元で指定できます。どうやらこの方法で、変更時にも対応できそうです。
後はフラッシュデーターのチェック方法です。フラッシュデーターの取得はInput::old()
を使います。このメソッドは引数なしで入力項目全部を配列で受け取るか、一つの項目を指定して、入力文字列を受け取るか、どちらかの使い方になります。残念ながら、only系メソッドのように配列で指定し、欲しい入力項目だけを受け取る使い方ができません。
フラッシュデーターの存在をチェックするInput::had()も存在しますが、これは単項目のチェックしか出来ません。しかも入力が空、つまりページでその項目が入力されなかった場合、セッションにフラッシュデーターとして存在していてもfalseが返ってきます。存在は存在でも、入力値が存在するかをチェックするメソッドのようです。
そこで、Input::old()
でフラッシュデーターとして保存されている入力を全部受け取り、array_only()で必要な2項目に絞ります。そしてその結果が空配列である、つまり有効なセッションデーターが存在しない場合は初回のアクセスとして取り扱い、空配列でない、つまり有効なセッションデーターが存在する場合は、その内容を表示するように処理します。
ちょっとややこしいですが、パターンを決めてしまえば、毎回やることは同じです。
チラ、チラ、チラ、なんだか…ビューの名前も…違っているような。
おや、バレちゃいましたか。add.blade.php
は追加だけをするビューでは無くなったので、form.blade.php
に名前を変えてください。内容は以下の通りです。
@layout('template') @section('title') 記事追加/編集 @endsection @section('content') {{ Form::open() }} <div> {{ Form::label('title', 'タイトル') }}<br> {{ Form::text('title', $title) }} @if ($errors->has('title')) <p style="color: red;">{{ $errors->first('title') }}</p> @endif </div> <div> {{ Form::label('body', '本文') }}<br> {{ Form::textarea('body', $body) }} @if ($errors->has('body')) <p style="color: red;">{{ $errors->first('body') }}</p> @endif </div> <div> {{ Form::submit('送信') }} </div> {{ Form::token() }} {{ Form::close() }} @endsection
今回の追加/更新のビューでは表示が単純です。ビューにwith()
で出力が渡されますから、$title
と$body
は必ず表示されます。表示内容の状況に合わせてセットされていますので、単純に表示するだけです。
さて、では動作を確認してみましょ…う、うーん。動作のためにポストIDを指定するのは面倒ですね。先にindex.blade.php
も変更しましょう。
@layout('template') @section('title') 一覧表示 @endsection @section('content') <table> <tr> <th>タイトル</th> <th>作成日</th> <th>更新</th> <th>削除</th> </tr> @foreach($posts as $post) <tr> <td>{{ HTML::link_to_route('post-show', $post->title ,array($post->id)) }}</td> <td>{{ $post->created_at }}</td> <td>{{ HTML::link_to_route('post-edit', '✜', array($post->id)) }}</td> <td>{{ HTML::link_to_route('post-delete', '✖', array($post->id)) }}</td> </tr> @endforeach </table> @endsection
更新へのリンクを付け加えただけです。もう、どこが違うか分かりますよね。