【问题标题】:Laravel deleting polymorph relations having possibly wrong relationsLaravel删除可能有错误关系的多态关系
【发布时间】:2015-06-30 09:40:39
【问题描述】:

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

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

【问题讨论】:

    标签: php laravel laravel-5 polymorphism eloquent


    【解决方案1】:

    Laravel 没有内置任何东西来自动删除相关记录。您需要自己构建此功能,这可以使用模型事件来完成。通常,我会设置一个 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;
            }
        }
    }
    

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

    public function boot(DispatcherContract $events) {
        parent::boot($events);
    
        RecipeComment::observe(new RecipeCommentObserver());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-03
      • 1970-01-01
      • 2018-11-03
      • 2015-05-15
      • 2020-08-02
      • 2018-05-19
      • 2020-07-31
      相关资源
      最近更新 更多