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,editdashboradの内容をコピー

layouts/owner-navigation.bladenavigation Linksなど編集していく→@62ab823

views/owner/shops/index.blade.php