Laravel学習帳

Laravel5.2の学習帳です。開発環境はXAMPP for Windows 5.6.19 / 本番環境はさくらサーバー(スタンダード)

基礎知識

編集画面を作成

2016/12/02

update06

WEBアプリの基本機能をCRUD(クラッド)といいます。

C・・・Create (新規作成)
R・・・Read (一覧表示)
U・・・Update (更新)
D・・・Delete (削除)

前回は上の例でいくとCreateをやりました。

フォームで入力したデータをDBのTABLEで保存

今回はUpdateの処理をやります。

 

編集画面のフロー

編集画面の主なフローは以下になります。

1. [View] リストごとに編集ページへのリンクをかける&レコードのidをパラメータにする
2. [routes] コントローラにとばす
3. [Controller] idを条件にしてレコードを抽出⇒Viewに連想配列で渡す
4. [View] inputタグのvalue属性にカラムの値を入れる
5. [routes] コントローラにとばす
6. [Controller] Eloquentでレコードの保存⇒HOME画面へリダイレクト
7. [View] HOME画面

ポイントはidを条件にしてレコードを抽出&保存するところですね。

これはモデルクラスのfindメソッドを使います。

モデル::find(主キー);

findOrFailメソッドを使うと検索結果が無い場合でもModelNotFoundException をスルーします。

findメソッドよりこちらを主に使います。

 

patchメソッドについて

編集フォームから値を送信するHTTPメソッドはpatchメソッドを利用します。

編集画面にはpatchメソッドを入れるわけですが、HTMLはpatchメソッドをサポートしていません。

この場合、隠しフィールドとしてフォームに追加します。

<input type="hidden" name="_method" value="PATCH">

ルーティングの設定でもHTTPはpatchを指定します。

Route::patch(' url ', ' コントローラ@メソッド ');

 

チュートリアル

以前作成した簡易フォームに編集画面を追加します。

 

実現したいこと

  1. 編集画面の作成
  2. UPDATEの処理

 

手順

1. 編集のページへのリンクを作成

前回一覧ページ(all.blade.php)を作成しましたが、そこに編集ボタンを追加します。

Bootstrapのtableクラスを利用してデザインを少し整形しました。

{{-- 子テンプレート --}}
{{-- resources/all.blade.php --}}
@extends('layouts.master')
@section('title', '入力した内容を表示するサンプルページ')
@section('content')
<p>{{$message}}</p>

<!-- ↓↓↓ 今回記述した箇所 ↓↓↓ -->
<table class="table table-striped">
  <!-- loop -->
  @foreach($data as $val)
  <tr>
  <td>{{$val->id}}</td>
  <td>{{$val->onamae}} さん</td>
  <td><a href="/mylaravel/public/greeting/edit/{{$val->id}}" class="btn btn-primary btn-sm">編集</a></td>
  </tr>
  @endforeach
</table>
<!-- ↑↑↑ 今回記述した箇所 ↑↑↑ -->

@endsection

 

2. ルーティングの設定

編集ボタンを押したときの処理を routes.php に記述します。

Route::get('/greeting/edit/{id}', 'GreetingController@edit');

上記の記述で

http://localhost/mylaravel/public/greeting/edit/[パラメータ]

にアクセスしたら

Greetingコントローラのeditメソッドが実行されるようになります。

 

3. コントローラにeditメソッドを追記

#app/Http/Controllers/GreetingController.php
:
#greeting/editにアクセスされた場合
public function edit($id)
{
  #レコードをidで指定
  $data = Greeting::findOrFail($id);

  #viewに連想配列を渡す
  return view('edit',['message' => '編集フォーム','data' => $data]);
}
:

 

4. 編集フォームの作成

入力フォーム(index.blade.php)をコピーして、それをカスタマイズして編集フォーム(edit.blade.php)にします。

{{-- 子テンプレート --}}
{{-- resources/edit.blade.php --}}
@extends('layouts.master')
@section('title', '入力した内容を表示するサンプルページ')
@section('content')

<p>{{$message}}</p>
<form class="form-signin" role="form" method="post" action="/mylaravel/public/greeting/update/{{$data->id}}">
<input type="hidden" name="_token" value="{{csrf_token()}}">
{{-- 隠しフィールド --}}
<input type="hidden" name="_method" value="PATCH">
<input type="text" name="onamae" value="{{ $data->onamae }}" class="form-control" placeholder="名前を文字を入力してください" autofocus>
  {{-- バリデーション --}}
  @if($errors->has('onamae'))
  <p class="text-danger" style="margin-bottom: 30px;">{{ $errors->first('onamae') }}</p>
  @endif
<button class="btn btn-lg btn-primary btn-block" type="submit">送信</button>
</form>
@endsection

 

5. ルーティングの設定&コントローラにupdateメソッド追加

編集フォームの送信メソッドはpatchなのでルーティングは以下のようになります。

#app/Http/routes.php
:
# 編集フォーム⇒UPDATE処理
Route::patch('greeting/update/{id}', 'GreetingController@update');
:

次にGreetingControllerにupdateメソッドを追加します。

#app/Http/Controllers/GreetingController.php
:
#DBの更新処理
  public function update(Request $request,$id)
  {
  $greeting = Greeting::findOrFail($id);
  $greeting->onamae = $request->input('onamae');
  $greeting->save();
  #return redirect('greeting',['status' => 'UPDATE完了!']); ←error!
  return redirect('greeting')->with('status', 'UPDATE完了!');
  }

上のコードを少し解説します。

return redirect('greeting')->with('status', 'UPDATE完了!');

DBの更新処理をしたあとに greeting.blade.php へリダイレクトさせます。

リダイレクト時にFlashメッセージを指定します。

 

6. greeting.blade.phpにFlashメッセージを表示

リダイレクト先のページでFlashメッセージを表示させます。

@if (session('status'))<div class="alert alert-success" role="alert" onclick="this.classList.add('hidden')">{{ session('status') }}</div>@endif

onclick="this.classList.add('hidden')" でクリックすると非表示になるように指定します。

全体のソースは以下になります。

{{-- 子テンプレート --}}
{{-- resources/greeting.blade.php --}}
@extends('layouts.master')
@section('title', '入力した内容を表示するサンプルページ')
@section('content')

{{-- ↓↓↓ 今回記述した箇所 ↓↓↓ --}}
@if (session('status'))<div class="alert alert-success" role="alert" onclick="this.classList.add('hidden')">{{ session('status') }}</div>@endif
{{-- ↑↑↑ 今回記述した箇所 ↑↑↑ --}}

<p>{{$message}}</p>
<form class="form-signin" role="form" method="post" action="/mylaravel/public/greeting">
<input type="hidden" name="_token" value="{{csrf_token()}}">
<input type="text" name="onamae" class="form-control" placeholder="名前を文字を入力してください" autofocus>
  {{-- バリデーション --}}
  @if($errors->has('onamae'))
  <p class="text-danger" style="margin-bottom: 30px;">{{ $errors->first('onamae') }}</p>
  @endif
<button class="btn btn-lg btn-primary btn-block" type="submit">送信</button>
</form>
@endsection

 

4. 動作確認

WEBサーバを起動して下記のURLにアクセス。

http://localhost/mylaravel/public/greeting/all

はじめて入力した laravel の文字を更新してみます。

"laravelさん"の文字の横にある編集ボタンをクリック。

update02
 

laravelの文字を削除してCodeigniterと入力しました。

update03
 

送信ボタンを押すと無事に"UPDATE完了!"というFlashメッセージが表示されました。

update04
 

Flashメッセージをクリックすると

onclick="this.classList.add('hidden')"

が働いて消えます。

update05
 

"一覧表示" のメニューをクリックしてみるとlaravelがCodeigniterにきちんと更新されているのが確認できました。

update06

 

はまったところ

redirect処理

テンプレートに値を渡す場合は

view( テンプレート , 連想配列 );

と、viewメソッドの第2引数に連想配列を指定していました。

redirectメソッドも同じような感じで以下のように記述しました。

return redirect('greeting',['status' => 'UPDATE完了!']);

これはエラーになります。

update01

redirectメソッドで値を渡す場合はwithを使います。

return redirect('greeting')->with('status', 'UPDATE完了!');

この記述でエラーが消えました。

新しいページヘリダイレクトした後、保存したメッセージ(status)を表示する方法は

@if (session('status'))
  <div class="alert alert-success">
  {{ session('status') }}
  </div>
@endif

この記述でOKです。

"alert alert-success" というCSSのクラスはBootstrapで用意されているCSSのクラスになります。

Cmponent Bootstrap

 

-基礎知識