Laravelで入力ページのバリデーション処理(実践編その4)

前回、『Laravelでバリデーション』で、バリデーションの方法を勉強しましたので、本日は、『Laravelでデータの新規作成』で、作成したページを実際にバリデーション処理を行ってみたいと思います。

1. collectionコントローラのcreateアクションを下記のように修正します。

laravel/application/controllers/collection.php

//新規作成createアクション
 public function action_create(){
 //もしデータが送信されたら
 if($data=Input::all()){
 //バリデーションルールの定義
 $rules=array(
 'title'=>'required|max:100',
 'col_code'=>'required|alpha_dash',
 'save_space'=>'required',
 );
 //バリデーションをインスタンス化
 $val=Validator::make($data,$rules);
 //バリデーションNGなら
 if($val->fails()){
 return Redirect::to('collection/create')->with_errors($val);
 }else{
 //EloquentORMでデータの新規作成
 $create=Collection::create($data);
 //トップページへリダイレクト
 return Redirect::to('collection/index');
 }
 }
 return View::make('collection/create');
 }
  • 4行目:前回、入力値の有無の条件判断にInput::get(‘title’)を使用しましたが、Input::all()でも入力値が無い場合emptyが返されますので、今回は、Input::all()を使用することにしました。こちらの方がいろんなフォームに対応できますので。
  • 7行目:requiredは必須項目です。条件を複数指定する場合は”|”で繋ぎます。
  • 12行目:Validatorクラスのmakeメソッドで、バリデーションをインスタンス化します。第1引数がバリデーションするデータの配列、第2引数がバリデーションルールの配列です。
  • 14行目:failsメソッドで、バリデーションの可否(true、false)を判断します。バリデーションNGの場合にtrueを返します。
  • 15行目:with_errorsメソッドで、エラーメッセージと共に、リダイレクトします。エラーメッセージは、$errors->項目名で取得することが出来ます。
  • 18~20行目:バリデーションOKならデータを登録して、トップページへリダイレクトします。

2. ビューページを下記のように修正します。

laravel/application/views/collection/create.blade.php

@layout('layouts.master')
@section('content')
{{ var_dump($errors->has('title')) }}
 {{ Form::open('collection/create','POST',array('class'=>'form-horizontal')) }}
 <fieldset>
@foreach($errors->all() as $row)
{{ "<div class='row'><div class='span6 offset2'><ul><li>".$row."</li></ul></div></div>" }}
@endforeach
 <div class="control-group {{ $errors->has('title') ? 'error' : '' }}">
 {{ Form::label('title','タイトル名',array('class'=>'control-label')) }}
 <div class="controls">
 {{ Form::text('title') }}
 {{ $errors->has('title') ? $errors->first('title','<p><span class="label label-important">:message</span></p>') : '' }}
 </div>
 </div>
 <div class="control-group">
 {{ Form::label('col_code','コード番号',array('class'=>'control-label')) }}
 <div class="controls">
 {{ Form::text('col_code') }}
 {{ $errors->has('col_code') ? $errors->first('col_code','<p><span class="label label-important">:message</span></p>') : '' }}
 </div>
 </div>
 <div class="control-group">
 {{ Form::label('save_space','保管場所',array('class'=>'control-label')) }}
 <div class="controls">
 <div class="control-group form-inline">
 {{ Form::text('save_space') }}
 {{ $errors->has('save_space') ? $errors->first('save_space','<p><span class="label label-important">:message</span></p>') : '' }}
 </div>
 </div>
 <div class="form-actions">
 {{ Form::submit('新規登録',array('class'=>'btn btn-primary')) }}
 </div>
 </fieldset>
 {{ Form::close() }}
 @endsection
  • 3行目:$errors->has(‘title’)メソッドの確認のための記述です。確認終了後に削除します。
  • 6~8行目:allメソッドで、全てのエラーを取得して表示します。
  • 13,20,28行目:$errors->has(項目名)メソッドで、エラーの有無を確認し、$errors->first(項目名)メソッドで、指定項目のエラーを表示します。

3. ブラウザで確認してみます。

http://localhost/laravel/public/collection/create

4. コード番号だけ入力して、新規登録ボタンをクリックしたら下記のようになりました。

バリデーション前の入力値

5. バリデーション処理をして、間違った入力値を指摘してくれるのはいいのですが、このままでは、正しい入力箇所も再度入力しなければなりません。同じデータを再入力しなくても済むようにするにはどうすればいいのでしょうか。

6. Laravelでは、Inputクラスのflashメソッドを使うことにより、直前の入力値を引き継ぐことが出来ます。そして引き継いだ値はoldメソッドで取得することが出来ます。

7. それでは、createアクションを下記のように修正します。

laravel/application/controllers/collection.php

//新規作成createアクション
 public function action_create(){
 //もしデータが送信されたら
 if($data=Input::all()){
 //バリデーションルールの定義
 $rules=array(
 'title'=>'required|max:100',
 'col_code'=>'required|alpha_dash',
 'save_space'=>'required',
 );
 //バリデーションをインスタンス化
 $val=Validator::make($data,$rules);
 //バリデーションNGなら
 if($val->fails()){
 //セッションに入力値を退避する
 Input::flash();
 return Redirect::to('collection/create')
 ->with_errors($val);
 }else{
 //EloquentORMでデータの新規作成
 $create=Collection::create($data);
 //トップページへリダイレクト
 return Redirect::to('collection/index');
 }
 }
 return View::make('collection/create');
 }

8. 次に、ビューファイルも下記のように修正します。

laravel/application/view/collection/create.blade.php

@layout('layouts.master')
@section('content')
 {{ Form::open('collection/create','POST',array('class'=>'form-horizontal')) }}
 <fieldset>
 <div class="control-group {{ $errors->has('title') ? 'error' : '' }}">
 {{ Form::label('title','タイトル名',array('class'=>'control-label')) }}
 <div class="controls">
 {{ Form::text('title',Input::old('title')) }}
 {{ $errors->has('title') ? $errors->first('title','<p><span class="label label-important">:message</span></p>') : '' }}
 </div>
 </div>
 <div class="control-group">
 {{ Form::label('col_code','コード番号',array('class'=>'control-label')) }}
 <div class="controls">
 {{ Form::text('col_code',Input::old('col_code')) }}
 {{ $errors->has('col_code') ? $errors->first('col_code','<p><span class="label label-important">:message</span></p>') : '' }}
 </div>
 </div>
 <div class="control-group">
 {{ Form::label('save_space','保管場所',array('class'=>'control-label')) }}
 <div class="controls">
 <div class="control-group form-inline">
 {{ Form::text('save_space',Input::old('save_space')) }}
 {{ $errors->has('save_space') ? $errors->first('save_space','<p><span class="label label-important">:message</span></p>') : '' }}
 </div>
 </div>
 <div class="form-actions">
 {{ Form::submit('新規登録',array('class'=>'btn btn-primary')) }}
 </div>
 </fieldset>
 {{ Form::close() }}
@endsection

9. ブラウザで確認してみます。復号化エラーが表示されました。

10. この状態になると、他のページも全く表示されません。Laravelはデフォルトでクッキーセッションを使用しています。クッキーの容量は4kbしかないので、容量オーバーが原因かと思い、ブラウザのクッキーを削除してみたら、元に戻りましたが、再度入力しようとしたら、又、同じ状態に戻ります。

11. そこで、セッションドライバーをデータベースに変更したら、下記のようにバリデーション前の入力値も表示できるようになりました。

12. と、いうことで、次回は『セッション設定』について調べたいと思います。

本日は以上です。

このエントリーを含むはてなブックマーク Buzzurlにブックマーク livedoorクリップ Yahoo!ブックマークに登録

トラックバック&コメント

この投稿のトラックバックURL:

トラックバック

コメント

  1. HiroKws より:

    こんにちは。
    好みもあるのですが、
    Input::flash();
    return Redirect::to(‘collection/create’)->with_errors($val);
    と同じ動作をさせるコードに:
    return Redirect::to(‘collection/create’)->with_errors($val)->with_input();
    があります。
    実は、上手く訳出できていないのですが、flash()やwith_input()はセッションに保存されても、フラッシュ・データーとして保存されます。フラッシュ・データーとは、現在と次のセッションの間のみ保存されるデーターです。次回のセッションで再度フラッシュ・データーとして保存したり、延命のためのSession::refresh()か、通常のセッションデータに移し替えるSession::keep()を行わない限り、次次回には自動的に消去されます。
    Session::refresh()は引数を取らず、対象は全フラッシュ・データーです。
    Session::keep()は保存データーのキーを指定します。一項目だけなら文字列、複数項目であれば、配列で渡します。

    • nakada より:

      川瀬 様
      コメントありがとうございます。
      まさしく、明日投稿予定の記事で、reflashメソッドとkeepメソッドの取り扱いを同じにするところでした。
      『reflashメソッドは、全体を再度保持して、keepメソッドは指定アイテムだけを再度保持する』という風に記述するところでした。
      川瀬様の情報で、keepメソッドは、通常のセッションデータに移行することが分かりました。
      早速記事を書き換えておきます。
      これからもよろしくお願いします。

  2. HiroKws より:

    その遠リ、refresh()ではなく、reflash()でした。

  3. HiroKws より:

    もうひとつ訂正です。reflash()は通常のセッションデーターに保存するのではなく、単に再度flash()するだけでした。
    お手数をかけますが、再度修正を願います。


コメントをどうぞ

このページの先頭へ