Как включить метод «удаления» загрузки модели Laravel в транзакцию БД с удалением основной модели?

#laravel #eloquent #transactions

#laravel #красноречивый #транзакции

Вопрос:

У меня есть модель, Agent и у нее много agent accounts .

 public function agentAccounts(): Relation
{
    return $this->hasMany(AgentAccount::class);
}
  

Я хочу удалить их за одну транзакцию, но используя boot метод

 public static function boot()
{
    parent::boot();

    self::deleting([self::class, 'onDeleting']);
}
  

Я понимаю, что когда я создаю транзакцию БД внутри функции «onDeleting», подобной этой

 public static function onDeleting(self $model): void
{
    DB::transaction(function () use ($model) {
        $agentAccounts = $model->agentAccounts;
        foreach ($agentAccounts as $agentAccount) {
            /* @var $agentAccount AgentAccount */
            $agentAccount->delete();
        }            
    }, 5);
}
  

Транзакция db не включает удаление самого агента.
Это предшествует транзакции db по удалению агента.
В моем случае удаление агента может завершиться неудачей из-за некоторых ограничений уровня SQL, не связанных с учетными записями агентов
и если я использую приведенный выше пример, я могу в конечном итоге удалить все учетные записи агентов, но сохранить агент.

Я не хочу, чтобы это произошло.

Я хочу, чтобы они либо удалялись вместе, либо сохранялись вместе.

Как я могу это сделать?

Комментарии:

1. Я не верю, что это будет возможно с событиями модели, если вы не перезапишете исходные методы eloquent, по какой-либо причине вы не хотите использовать ->onDelete('cascade') для AgentAccount внешнего ключа Agent ? Таким образом, он автоматически удалит все учетные записи, если агент будет успешно удален.

2. Спасибо. «каскад» не настолько гибкий, я упростил вопрос. На самом деле есть условия и задействовано больше таблиц.

Ответ №1:

Я считаю, что события DB выполняются в режиме блокировки, поэтому при вызове delete() модели достаточно сделать это внутри транзакции, вот так

 DB::transaction(function () use($user) { $user->delete(); });