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 App\Http\Controllers;
use App\Http\Requests\AddUserRequest;
use App\Http\Requests\EditUserRequest;
use App\User;
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版と、確認画面付きの版を試します。