Как мягко удалить связанные записи при мягком удалении родительской записи в Laravel?

У меня есть эта таблица счетов, которая имеет следующую структуру

id | name | amount | deleted_at
2    iMac   1500   | NULL

и таблица платежей со следующей структурой

id | invoice_id | amount | deleted_at
2    2            1000   | NULL

Модель счета

class Invoice extends Model {

use SoftDeletes;

}

вот код для удаления счета

public function cance(Request $request,$id)
{
$record = Invoice::findOrFail($id);
$record->delete();
return response()->json([
'success' => 'OK',
]);
}

Модель платежей

class Payment extends Model {

use SoftDeletes;

}

SoftDelete для таблицы Invoice работает отлично, но связанные с ней записи (платежи) все еще существуют. Как удалить их с помощью softDelete?

12

Решение

красноречивый не обеспечивает автоматического удаления связанных объектов, поэтому вам нужно будет написать код самостоятельно. К счастью, все довольно просто.

Красноречивые модели запускать различные события на разных этапах жизненного цикла модели, такие как создание, создание, удаление, удаление и т. д. — об этом можно прочитать здесь: http://laravel.com/docs/5.1/eloquent#events. Вам нужен слушатель, который будет работать, когда удаленный событие инициируется — этот слушатель должен затем удалить все связанные объекты.

Вы можете зарегистрировать слушателей модели в вашей модели загрузки () метод. Слушатель должен выполнить итерацию всех платежей за удаляемый счет-фактуру и удалить их один за другим. Массовое удаление здесь не будет работать, так как оно будет выполнять SQL-запрос напрямую, минуя события модели.

Это сделает свое дело:

class MyModel extends Model {
protected static function boot() {
parent::boot();

static::deleted(function ($invoice) {
$invoice->payments()->delete();
});
}
}
12

Другие решения

Вы можете пойти одним из двух способов с этим.

Простейшим способом было бы переопределить Eloquents delete() метод и включить соответствующие модели, например:

public function delete()
{
$this->payments()->delete();
return parent::delete();
}

Вышеупомянутый метод должен работать просто найти, но он выглядит немного грязным, и я бы сказал, что это не самый предпочтительный метод в сообществе.

Более чистым способом (IMO) было бы использование событий Eloquents, например:

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

static::deleting(function($invoice) {
$invoice->payments()->delete();

});
}

Любой (но не оба) из вышеперечисленных методов будет идти в вашем Invoice модель.
Кроме того, я предполагаю, что ваши отношения настроены в вашей модели, однако я не уверен, разрешаете ли вы несколько платежей за один счет. В любом случае вам может понадобиться изменить payments() в примерах к тому, что вы назвали отношения в вашей модели счета.

Надеюсь это поможет!

9

Я знаю, что вы задавали этот вопрос давным-давно, но я нашел этот пакет быть очень простым и понятным.

Или вы можете использовать этот пакет это тоже полезно.

Помните установить правильную версию в зависимости от вашей версии Laravel.

Вы должны установить его через композитор:

 composer require askedio/laravel5-soft-cascade ^version

Во втором пакете:

 composer require iatstuti/laravel-cascade-soft-deletes

Зарегистрируйте поставщика услуг в вашем config / app.php.

Вы можете прочитать документы на странице GitHub.

Если вы удалите запись, этот пакет распознает все ее дочерние элементы и также удалит их.

Если у вас есть другие отношения в вашей дочерней модели, используйте эту черту и в этой модели. это намного проще, чем делать это вручную.

Второй пакет имеет преимущество удаления внуков модели. в некоторых случаях я говорю, что это лучший подход.

4
По вопросам рекламы [email protected]