Laravel удаляет полиморфные отношения, имеющие возможно неправильные отношения

У меня есть модель, которая представляет отчет от пользователя. Модель отчета имеет полиморфное отношение, которое может содержать либо рецепт, либо комментарий.

Цель состоит в том, чтобы иметь возможность удалить комментарий или пользователя и удалить связанные отчеты с помощью eloquent.

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

Что я делаю неправильно? Нужно ли мне иметь отношение «принадлежат» на моей полиморфной модели? Если так, как я могу построить эти отношения, когда связь может быть изменена?


модели

Полиморфная модель

class Report extends Model {
public function reportable() {
return $this->morphTo();
}

public function User() {
return $this->belongsTo('App\User');
}
}

Рецепт Модель

class Recipe extends Model {
public function user() {
return $this->belongsTo('App\User');
}

public function reports() {
return $this->morphMany('App\Report', 'reportable');
}
}

Модель комментария

class RecipeComment extends Model {
public function user() {
return $this->belongsTo('App\User');
}

public function reports() {
return $this->morphMany('App\Report', 'reportable');
}
}

4

Решение

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

Ларавел 5 модельный наблюдатель будет выглядеть примерно так:

class RecipeCommentObserver {
public function deleting($model) {
try {
DB::transaction(function() use ($model) {
/**
* Try to delete the necessary related objects when this object is deleted.
*/

// detach the many-manys from this model, which will delete
// the records in the pivot table.
// e.g. if you had a many-many relationship named 'tags':
// $model->tags()->detach();

// the one-one and one-many relations to try and delete
// for your example, you probably only want 'reports' here.
// you probably don't to delete the user when deleting a comment.
$relations = ['reports'];

foreach ($relations as $relation) {
// get a list of all the related ids for this relation
$ids = $model->$relation()->lists('id');

// use the ->destroy method so any events get fired for the deleted objects
// if the amount deleted is less than expected, an error occurred
if (!empty($ids) && $model->$relation()->getRelated()->destroy($ids) < count($ids)) {
throw new Exception('Error occurred deleting ' . $relation);
}
}
});
} catch (Exception $e) {
throw $e;
}
}
}

С помощью этой настройки класса вы регистрируете наблюдателя в boot() метод в app/Providers/EventServiceProvider.php:

public function boot(DispatcherContract $events) {
parent::boot($events);

RecipeComment::observe(new RecipeCommentObserver());
}
1

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

Других решений пока нет …

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