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インスタンスを読み込んでくれる。
なければインスタンスを作る。ただしレコードは作らない。新規作成操作時にレコードを作成する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?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は載せていません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?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)は何でも良いので載せていません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
@extends('layouts.app') @section('content') <div class="form-group"> <h3>@if (isset($user->id))編集 @else 追加 @endif</h3> </div> @if ($user->wasRecentlyCreated) {!! Form::model($user,['route'=>['postEditUser',$user->id],'class'=>'form-horizontal'])!!} @else {!! Form::model($user,['route'=>['postAddUser'],'class'=>'form-horizontal'])!!} @endif <div class="form-group"> {!! 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 <div class="invalid-feedback">{!! $errors->first('name') !!}</div> </div> <div class="form-group"> {!! 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 <div class="invalid-feedback">{!! $errors->first('email') !!}</div> </div> <div class="form-group"> {!! Form::label('password', 'password :') !!} @if($errors->has('password')) {!! Form::password('password',['class'=>'form-control is-invalid']) !!} @else {!! Form::password('password',['class'=>'form-control']) !!} @endif <div class="invalid-feedback">{!! $errors->first('password') !!}</div> </div> <div class="form-group"> @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 </div> {!! Form::close() !!} @endsection |
まとめ
relationもないし懸案の確認画面もないので、単純。
次回、has a、has many relation版と、確認画面付きの版を試します。