在 Laravel 6 中同时保存两个相互关联的新模型

Save two new models with a relationship to each other at once in Laravel 6

我想知道同时保存两个相互关联的不同模型的最佳方法是什么。假设我有一个订阅模型和一个参与者模型,当我创建一个参与者时,它必须创建一个订阅和 link 参与者。

示例:

class Subscription extends Model
{
    public function participants()
    {
        return $this->hasMany('App\Participant');
    }
}

class Participant extends Model
{
    public function subscription()
    {
        return $this->belongsTo('App\Subscription');
    }
}

节省:

$s = new App\Subscription();

$p = new App\Participant();

$s->participants()->save($p);

但是订阅没有保存。有什么想法可以同时保存它们,检查它们是否已保存并建立关系?

您要找的是交易。你可以用两种方法来做。

使用 DB::transaction() 并将所有内容放入闭包中

use DB;

$s = new App\Subscription();
$p = new App\Participant();

DB::transaction(function () use ($s, $p) {
    // If something fails, it will rollBack, if not, it will commit.
    $s->save();
    $s->participants()->save($p);
});

或手动控制何时提交或回滚。

use DB;

$s = new App\Subscription();
$p = new App\Participant();

try {
    DB::beginTransaction();
    $s->save();
    $s->participants()->save($p);
    DB::commit();
} catch (\Exception $e) {
    DB::rollBack();
}

More info on transactions

您可以通过交易来做到这一点(如@IGP 的回答),或者也可以为订阅添加保存行..

public function test()
{
    // Begin Transaction
    DB::beginTransaction();

    try
    {
        $participant = new Participant();

        $subscription = new Subscription();
        // $subscription->name = "parent subscription"; // init necessary columns
        $subscription->save();

        $participant->subscription()->associate($subscription);
        // $participant->name = "child participant"; // init necessary columns
        $participant->save();

        // Commit Transaction
        DB::commit();

        // Continue your logic here

    } catch (\Exception $e) {
        // Rollback Transaction
        DB::rollback();

        return $e->getMessage();
    }
}