php – Laravel删除可能存在错误关系的多态关系

我有一个代表用户报告的模型.报表模型具有多态关系,可以包含配方或注释.

目标是能够删除评论或用户,并通过eloquent删除相关报告.

使用我当前的设置(如下所示),这不起作用,当删除评论时报告仍然存在并导致错误,因为它现在指向不存在的评论.

我究竟做错了什么?我的多态模型是否需要“belongsTo”关系?如果是这样,当关系是可变形的时候,我该如何建立这种关系呢?

楷模

多态模型

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

解决方法:

Laravel没有内置任何内容来自动删除相关记录.您需要自己构建此功能,这可以使用Model事件完成.通常,我设置了一个删除事件,负责删除事务中的相关记录.

Laravel 5 model observer看起来像这样:

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

使用此类设置,您可以在app / Providers / EventServiceProvider.php中的boot()方法中注册观察者:

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

    RecipeComment::observe(new RecipeCommentObserver());
}
上一篇:mysql – Laravel的回滚事务是否支持多态关系?


下一篇:c# – 在没有警告的情况下隐藏基类的显式接口实现的目的?