1枚のBladeで確認画面付きCRUDを実現できると、Bladeの枚数が格段に少なくなって良さそう。
その前にまずModelBindingで単なるUserを1枚のBladeでCRUDしてみる。
1枚のBladeが複数の機能で使われることになり、Bladeの中に要素と制御が増えていくため、
実は、Bladeの枚数が増えたとしても1つのBladeを単純にした方が良いのかもしれないが、
1度作っておくとずっと使えるかもしれないので、そこまでやってみる。
やること
Laravelに最初から付いてくるUserを使って、name,email,passwordのCRUDをする。
URL(route)は以下。showのパラメタをOptionalにして、あればUpdate、なければCreateする。
Update、Createは、本質的に分けるべきと考えてURLを別にしてある。
firstOrNew()を使うと、あればUserインスタンスを読み込んでくれる。
なければインスタンスを作る。ただしレコードは作らない。新規作成操作時にレコードを作成する。
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the \"web\" middleware group. Now create something great!
|
*/
Route::get(\'/user/{user?}\',\'UserController@show\');
Route::post(\'/user/\',\'UserController@add\')->name(\'postAddUser\');
Route::post(\'/user/{user}\',\'UserController@edit\')->name(\'postEditUser\');
コントローラ
コントローラは以下。無条件に保存するだけなのでほとんど何も書いてない。
条件が増えてくるとそれなりに行数が増える。
ModelBindingの良さは、タイプヒンティングでEloquentのインスタンスを受けられること。
変数を受けてEloquentインスタンスを探す手間がバッサリ無い。
RequestValidatorは載せていません。
<?php
namespace AppHttpControllers;
use AppHttpRequestsAddUserRequest;
use AppHttpRequestsEditUserRequest;
use AppUser;
class UserController extends Controller
{
public function show($id=null)
{
$user = User::firstOrNew([\'id\'=>$id]);
return view(\'user\',compact(\'user\'));
}
public function add(User $user,AddUserRequest $request)
{
$user->fill($request->only([\'name\',\'email\',\'password\']))->save();
return view(\'user\',compact(\'user\'));
}
public function edit(User $user,EditUserRequest $request)
{
$user->fill($request->only([\'name\',\'email\',\'password\']))->save();
return view(\'user\',compact(\'user\'));
}
}
Blade
肝心のBladeは以下。これだけなのに結構書かないといけない。
laravelcollective/htmlは大分前にLaravelから外れていて、使わない方が良いのかも。
自力でHTMLを書くのと大して労力が変わらない可能性がある。
結構書かないといけないから1枚にしたいのか、複数枚でよければあまり書かなくて良いのか、
微妙なところ。Laravel5.7なのでBootstrap4。validation用のクラスが全然違う。
親Blade(layouts.app)は何でも良いので載せていません。
@extends(\'layouts.app\')
@section(\'content\')
@if (isset($user->id))編集 @else 追加 @endif
@if ($user->wasRecentlyCreated)
{!! Form::model($user,[\'route\'=>[\'postEditUser\',$user->id],\'class\'=>\'form-horizontal\'])!!}
@else
{!! Form::model($user,[\'route\'=>[\'postAddUser\'],\'class\'=>\'form-horizontal\'])!!}
@endif
{!! Form::label(\'name\', \'名前 :\') !!}
@if($errors->has(\'name\'))
{!! Form::text(\'name\',$user->name,[\'class\'=>\'form-control is-invalid\']) !!}
@else
{!! Form::text(\'name\',$user->name,[\'class\'=>\'form-control\']) !!}
@endif
{!! $errors->first(\'name\') !!}
{!! Form::label(\'email\', \'email :\') !!}
@if($errors->has(\'email\'))
{!! Form::email(\'email\',$user->email,[\'class\'=>\'form-control is-invalid\']) !!}
@else
{!! Form::email(\'email\',$user->email,[\'class\'=>\'form-control\']) !!}
@endif
{!! $errors->first(\'email\') !!}
{!! Form::label(\'password\', \'password :\') !!}
@if($errors->has(\'password\'))
{!! Form::password(\'password\',[\'class\'=>\'form-control is-invalid\']) !!}
@else
{!! Form::password(\'password\',[\'class\'=>\'form-control\']) !!}
@endif
{!! $errors->first(\'password\') !!}
@if($user->wasRecentlyCreated)
{!! Form::submit(\'保存\',[\'class\'=>\'btn btn-primary form-control col-sm-2\']) !!}
@else
{!! Form::submit(\'新規作成\',[\'class\'=>\'btn btn-primary form-control col-sm-2\']) !!}
@endif
{!! Form::close() !!}
@endsection
まとめ
relationもないし懸案の確認画面もないので、単純。
次回、has a、has many relation版と、確認画面付きの版を試します。