Laravel shop一覧、編集画面遷移、transaction、例外処理
- ownersとshopsテーブルの関係
shop作成、transaction、編集画面
shop作成
1つのownerが1つのshopをもつのでowner登録をした際に同時にshopも作るようにする。
→ownerを作成するのはadmin側なので、adminでownerを登録した際にshopも作成する。
- 編集画面遷移
findOrFail($id)
でパラメータ取得→なければ404返す。
<?php namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use App\Models\Owner; //Eloquent use App\Models\Shop; use App\Services\Owner\OwnerService; use Illuminate\Support\Facades\DB; //クエリビルダ use Illuminate\Support\Facades\Log; use Throwable; //コンストラクタでミドルウェアを設定しadminで認証していた場合実行する public function __construct() { $this->middleware('auth:admin'); } /** * フォームで入力された値がRequestクラスとなってそれをインスタンス化$requestする * (メソッドインジェクション * controllers/admin.auth/registerUserControllerからコピペ */ public function store(Request $request) { $request->validate([ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:owners'], 'password' => ['required', 'string', 'confirmed', 'min:8'], ]); $result = OwnerService::addByOwner($request); if(is_string($result)){ return back(); } return redirect()->route('admin.owners.index')->with(['message' => 'オーナーを登録できました。','status'=>'info']); } public function edit($id) { $this->viewData['owner'] = Owner::findOrFail($id); return view('admin.owners.edit', $this->viewData); }
transaction
ownerを作成後shopも作るので2つのテーブルに保存することになる。
この場合はtransactionをかける必要がある。
- transaction
処理の最中に何かしらのトラブルがあって止まったりした場合、1つ目は処理できて2つ目が処理できていないのはまずい。
→DB::beginTransaction();
でまとめて処理することができ、途中で処理がとまったらDB::rollback;
でロールバックされる。
システム内にエラーが発生しているのに、後続処理が続くのはまずい。
→継続処理すると、後ろの処理が全部通ってしまい、途中でエラーが発生しても、最後まで正常終了となる場合がある。
サービスへ切り出し
- 例外処理 Exception $e おきまり作法
もしエラーが出た場合、catch 以下の処理 ロールバックでもどる
DB::commit();
でまとめて処理する
<?php class OwnerService{ public static function addByOwner($request){ DB::beginTransaction(); try { $owner = Owner::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), //Hash::makeで暗号化 ]); Shop::create([ 'owner_id' => $owner->id, 'name' => '店名を入力してください', 'information' => '', 'filename' => '', 'is_selling' => true ]); } catch (\Exception $e) { Log::error($e); DB::rollback; } DB::commit(); } }
Shop::create
で作成する場合は モデル側に $fillable
も必要
<?php class Shop extends Model { use HasFactory; protected $fillable = [ 'owner_id', 'name', 'information', 'filename', 'is_selling', ]; public function owner() { return $this->belongsTo(Owner::class); } }
shop一覧表示
route
<?php Route::get('/', function () { //prefix設定 return view('owner.welcome'); }); //shopのルート Route::prefix('shops')-> middleware('auth:owners')->group(function(){ Route::get('index', [ShopController::class, 'index'])->name('shops.index'); Route::match(['get','post'],'edit/{shop}', [ShopController::class, 'edit'])->name('shops.edit'); });
Controller
php artisan make:controller Owner/ShopController
ログインしてるかの認証をコンストラクタでかける
→__construct で$this->middleware(‘auth:owners’):
index一覧表示
→ログインしているownerのIDを取得しつつownerの作成したshopを取得したい
use Illuminate\Support\Facades\Auth;
$ownerId = Auth::id();
とすることでログインしているIDを取得できる1人のownerが複数のshopを持ちたい
→Shop::where(‘owner_id’, $ownerId)->get();
と書ける。
まとめて書く→Shop::where('owner_id', Auth::id())->get();
<?php namespace App\Http\Controllers\Owner; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use App\Models\Shop; class ShopController extends Controller { //コンストラクタでミドルウェアを設定しownerで認証していた場合実行する public function __construct() { $this->middleware('auth:owners'); } public function index() { //ログインしているオーナーのIDを取得 $ownerId = Auth::id(); //1人のownerが複数のshopをもちたいので、owner_idをログインしている$ownerIDでwhereで検索してgetすればよい $this->viewData['shops'] = Shop::where('owner_id', $ownerId)->get(); return view('owner.shops.index', $this->viewData); }
view
views/owner
配下にshops
フォルダ作成
→resources/views/owner/shops/edit.blade.php
resources/views/owner/shops/index.blade.php
index
,edit
にdashborad
の内容をコピー
layouts/owner-navigation.blade
のnavigation Links
など編集していく→@62ab823
views/owner/shops/index.blade.php