ウェブのプログラミングでなんといっても難しいのはフォーム画面のプログラムです。テキスト入力、ドロップダウン、ファイルのアップロード機能、さらにjqueryやangularなどのフロントエンドのjavascriptも入れば、無限の可能性があります。

以前紹介したLaravelの付録の会員認証サンプルの会員登録画面は、php artisan make:authコマンドで自動作成されますが、ログイン後に会員がEメールアドレスや名前を編集する画面は作成されません。

今回はこの編集画面を作成してみます。

まず、新規のコントローラ作成します。

php artisan make:controller User/UserController

を実行して、それを以下のように編集し、

namespace App\Http\Controllers\User;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\User;

use Auth;
use Validator;

class UserController extends Controller
{
    protected $user;

    public function __construct()
    {
        $this->middleware('auth:user'); // 認証

        $this->user = Auth::guard('user')->user();
    }

    public function getProfile()
    {
        return view('user/profile')->with(['user' => $this->user]);
    }

    public function postProfile(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name'  => 'required|max:255',
            'email' => 'required|email|max:255|unique:users,email,'.$this->user->id
        ]);

    // エラーチェック
        if ($validator->fails())
        {
            return back()->withInput()->withErrors($validator);
        }

    // データを更新
        $this->user->update([
            'name'  => $request->input('name'),
            'email' => $request->input('email')
        ]);

        return redirect('user/home');
    }
}

Validationでは、emailのチェックは、$this->user->idを除くusersのレコードを対象に他に同じEメールが使われていないかチェックします。

次に、以下のようなテンプレートを作成します。

@extends('user.layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Profile</div>
                <div class="panel-body">
                    <form class="form-horizontal" role="form" method="POST" action="{{ url('/user/profile') }}">
                        {!! csrf_field() !!}

                        <div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
                            <label class="col-md-4 control-label">名前</label>

                            <div class="col-md-6">
                                <input type="text" class="form-control" name="name" value="{{ old('name', $user->name) }}">

                                @if ($errors->has('name'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('name') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

                        <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
                            <label class="col-md-4 control-label">Eメール</label>

                            <div class="col-md-6">
                                <input type="email" class="form-control" name="email" value="{{ old('email', $user->email) }}">

                                @if ($errors->has('email'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('email') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    保存
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

ここ、old()のLaravelの関数が使用されていますが、すでに存在する値を編集するので、デフォルトとしてDBからの値が入っていることに注意してください。

 <input type="text" class="form-control" name="name" value="{{ old('name', $user->name) }}">

コントローラでは、validationエラーが発生して、現在の画面に戻る必要があります。そのときは、withInput()がセッションに入力の値を保存して、back()で現在の画面にリダイレクトします。リダイレクト後には、old()は、デフォルトでなくセッションに保存された入力された値を表示します。

最後に、routes.phpを以下のように編集します。

Route::group(['prefix' => 'user', 'middleware' => 'web'], function () {
...
    Route::get('profile', 'User\UserController@getProfile');
    Route::post('profile', 'User\UserController@postProfile');
});

以下のように、認証のミドルウェアをコントローラから移してもOKです。

Route::group(['prefix' => 'user', 'middleware' => 'web'], function () {
...
   Route::group(['middleware' => 'auth:user' ], function () {
        Route::get('home', 'User\HomeController@index');
        Route::get('profile', 'User\UserController@getProfile');
        Route::post('profile', 'User\UserController@postProfile');
    });
});

By khino