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

时间:2019-10-03 09:22:34

标签: laravel eloquent laravel-6 eloquent--relationship

我想知道一次保存两个相互关联的不同模型的最佳方法是什么。考虑到我有一个订阅模型和一个参与者模型,当我创建一个参与者时,它必须创建一个订阅并将参与者链接到它。

示例:

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);

但是,订阅没有保存。有什么想法是最好的做法是同时保存它们,检查它们是否已保存并建立联系?

2 个答案:

答案 0 :(得分:0)

您要寻找的是交易。您可以通过2种方式进行操作。

使用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

答案 1 :(得分:0)

您可以使用交易来完成此操作(如@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();
    }
}