🛢

[Laravel] DB::transaction() 内で生成したオブジェクトをメソッドの外で使いたい

Laravel のトランザクションには、2 通りの書き方がある。

1 つは、try catch を使う方法。

DB::transaction();

try {
    $user = User::create($request->all());
    DB::commit();
} catch (\Exception $e) {
    DB::rollback();
}

もう 1 つは、DB::transaction() を使う方法。

DB::transaction(function () use ($request) {
    $user = User::create($request->all());
});

後者のほうがきれいで読みやすいけれど、後者では transaction の外で $user を参照できないので、 transaction のなかで生成したモデルを transation の外で使いたい場合に困ってしまう。

public function store(Request $request)
{
    DB::transaction(function() use($request){
        $user = User::create($request->all());
    });

    // $userを参照できない!
    return redirect()->route('user.show', compact('user'));
}

解決方法

それを解決する方法として、DB::transaction()$user を返すようにする、というのがある。

$user = DB::transaction(function () use ($request) {
    return User::create($request->all());
});

これなら、以下のコードでも困らない。

public function store(Request $request)
{
    $user = DB::transaction(function() use($request){
        return User::create($request->all());
    });

    // $userを参照できる!
    return redirect()->route('user.show', compact('user'));
}