Laravel

Laravelでデータの更新(実践編その5)

更新日:

今日は、『Laravelでデータの新規作成』で作成したデータの更新方法を調べてみたいと思います。editアクションとeditビューを作成しますが、その前にindexビューから指定データへ移動できるようにしたいと思います。

1. index.blade.phpを下記のように修正します。

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

@layout('layouts.master')
@section('navigation')
 <li>{{ HTML::link('collection/index','トップページ') }}</li>
 <li>{{ HTML::link('collection/create','新規作成') }}</li>
@endsection
@section('content')
<table class="table table-striped table-bordered">
 <tr>
 <th>id</th>
 <th>タイトル</th>
 <th>作成日</th>
 <th>更新日</th>
 <th>保管場所</th>
 <th>処理</th>
 </tr>
@foreach($collections as $row)
 <tr>
 <td>{{ $row->id }}</td>
 <td>{{ $row->title }}</td>
 <td>{{ $row->created_at }}</td>
 <td>{{ $row->updated_at }}</td>
 <td>{{ $row->save_space }}</td>
 <td>{{ HTML::link_to_action('collection@edit','更新',array($row->id)) }}</td>
 </tr>
@endforeach
</table>
{{ $links }}
@endsection
  • 2~5行目:マスタービューのnavigationをビューファイルから修正するために記述しています。マスタービューを書き直さなくてもこのような使い方で、既存のナビゲーションを修正できます。下図①
  • 23行目:link_to_actionメソッドで、コントローラアクションへのリンクを生成します。第1引数がコントローラアクションのパス、第2引数が表示文字列、第3引数がワイルドカード値です。下図②。下記のようなリンクを生成します。
     http://localhost/laravel/public/collection/edit/183 
  • 27行目:ページネーション用のリンクです。下図③

※尚、collection@editで使用しているパスの指定方法ですが、公式ドキュメントでアットマーク"@"になっていたので、"@"で記述していますが、ピリオド"."でも、スラッシュ"/"でも同じURLを生成します。この違いが今のところ不明です。理由が判明したら後日お知らせしたいと思います。

2. ブラウザではこんな感じになります。

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

Fluentクエリービルダーでデータの更新

3. collectionコントローラにeditアクションを作成します。

laravel/application/controllers/collection.php 

//更新ページeditアクション
 public function action_edit($id=null){
 //もしデータが送信されたら
 if($input=Input::all()){
 //バリデーションルールの定義
 $rules=array(
 'title'=>'required|max:100',
 'col_code'=>'required|alpha_dash',
 'save_space'=>'required',
 );
 //バリデーションをインスタンス化
 $val=Validator::make($input,$rules);
 //バリデーションNGなら
 if($val->fails()){
 //エラーと一緒に現ページへリダイレクト
 return Redirect::to(URL::current())
 ->with_errors($val)
 }else{
 //Fluentクエリービルダーでデータの更新
 $update=DB::table('collections')
 // Where句でデータの選択
 ->where('id','=',Input::get('id'))
 /* 動的Where句でデータの選択
 ->where_id(Input::get('id'))*/
 ->update($input);
 //トップページへリダイレクト
 return Redirect::to('collection/index');
 }
 }
 //Fluentクエリービルダーでデータを取得
 $data['collections']=DB::table('collections')->find($id);
 return View::make('collection/edit',$data);
 }
  • 16行目:リダイレクト先は、ワイルドカードも一緒に指定しないといけないので、現在のURLを取得するURL::current()メソッドを使用しています。
  • 24行目:コメントアウトしていますが、22行目と全く同じ動作をします。Laravelでは、動的Whereメソッドを使用することにより、コードの記述をこのように簡略化できます。

3. editビューを下記のように作成します。

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

@layout('layouts.master')
@section('navigation')
 <li>{{ HTML::link('collection/index','トップページ') }}</li>
 <li>{{ HTML::link('collection/create','新規作成') }}</li>
@endsection
@section('content')
 {{ Form::open(URL::current(),'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',$collections->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',$collections->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">
 {{ Form::text('save_space',$collections->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::hidden('id',$collections->id) }}
 {{ Form::submit('データ更新',array('class'=>'btn btn-primary')) }}
 </div>
 </fieldset>
 {{ Form::close() }}
@endsection

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

http://localhosst/laravel/pulbic/collection/edit/183

5. タイトル名を修正してみます。下記のようになりました。

EloquentORMでデータの更新

6. 次はEloquentORMでデータを更新してみたいと思います。editアクションを下記のように修正します。

laravel/public/contorollers/collection.php 

//更新ページeditアクション
 public function action_edit($id=null){
 //もしデータが送信されたら
 if($input=Input::all()){
 //バリデーションルールの定義
 $rules=array(
 'title'=>'required|max:100',
 'col_code'=>'required|alpha_dash',
 'save_space'=>'required',
 );
 //バリデーションをインスタンス化
 $val=Validator::make($input,$rules);
 //バリデーションNGなら
 if($val->fails()){
 //エラーを取得して現ページへリダイレクト
 return Redirect::to(URL::current())
 ->with_errors($val);
 }else{
 //EloquentORMでデータの更新
$update=Collection::where_id(Input::get('id'))
 ->update($input);
//トップページへリダイレクト
 return Redirect::to('collection/index');
 }
 }
 //EloquentORMでデータを取得
 $data['collections']=Collection::find($id);
 return View::make('collection/edit',$data);
 }

7. データを更新してブラウザで確認してみます。

8. データは更新されているのですが、updated_atの値が更新されていません。timestampプロパティをtrueにして、モデルに記述したりしてみたのですが、やはり、updated_atは更新されません。createメソッドでは、created_atとupdated_atが自動的に記述されるのですが、updateメソッドでは、自動的に更新されるようになっていないみたいです。

9. updated_atを自動更新するには、findメソッドでプライマリーキーを指定し、モデルの各プロパティに値を入力後、saveメソッドを使う必要があるみたいです。19~21行目を下記のように修正します。

//EloquentORMでデータの更新
 $update=Collection::find(Input::get('id'));
 $update->title=Input::get('title');
 $update->col_code=Input::get('col_code');
 $update->save_space=Input::get('save_space');
 $update->save();

10. これで、再度データを更新したら、updated_at(更新日)も更新されていました。updateメソッドでもupdated_atを自動更新する方法があったら後日ご報告します。

本日は、以上です。

-Laravel
-

Copyright© WinRoad徒然草 , 2018 All Rights Reserved Powered by AFFINGER5.