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

时间:2015-04-22 15:40:55

标签: php laravel laravel-5 polymorphism eloquent

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

目标是能够删除评论或用户,并通过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');
    }
}

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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