【问题标题】:Laravel Eloquent Cascading DeletesLaravel Eloquent 级联删除
【发布时间】:2014-05-07 12:53:31
【问题描述】:

我正在使用 Laravel 4.1 并正在尝试级联删除。我这样做是因为一些删除方法会删除存储在 S3 上的关联资产,因此依赖 DB 级联删除是不合适的。

假设我有一个 Entry 模型,它本身有一个图像和许多相关的 Option,它们也有如下所示的图像(为了简洁而减少)。

class Entry extends Eloquent {
    public function image()
    {
        return $this->morphOne('Image', 'imageable');
    }

    public function options()
    {
        return $this->hasMany('Option');
    }

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

        static::deleting(function($entry) {
            $image = $entry->image;
            if($image !== null) {
                $image->delete();
            }

            $entry->options()->delete()
            //Option::where('entry_id', $entry->id)->delete(); This also doesn't work
        });
    }
}

class Option extends Eloquent {

    public function entry()
    {
        return $this->belongsTo('Entry');
    }

    public function image()
    {
         return $this->morphOne('Image', 'imageable');
    }

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

        static::deleting(function($option) {
            Log::info('Trying to delete an option object');
            $image = $option->image;

            if($image !== null) {
                $image->delete();
            }
        });
    }
}

注意:我正在按照this answer 中的建议进行删除。

当我调用 $entry->delete() 时,它将删除图像和条目本身,但是永远不会在选项上调用删除处理程序(我没有看到它输出到日志)。但是,如果我在条目删除功能中使用以下内容,一切正常。

foreach($entry->options as $option) {
    $option->delete();
}

为什么 $entry->options()->delete() 不起作用?这是 Laravel 中的错误还是我犯了一个错误。

【问题讨论】:

    标签: php laravel-4


    【解决方案1】:
    class Entry extends Eloquent {
        public function image()
        {
            return $this->morphOne('Image', 'imageable');
        }
    
        public function options()
        {
            return $this->hasMany('Option');
        }
    
        protected static function boot() {
            parent::boot();
    
            static::deleting(function($entry) {
                $image = $entry->image;
                if($image !== null) {
                    $image->delete();
                }
    
                $entry->options->each(function($option) {
                    $option->delete();
                });
                //Option::where('entry_id', $entry->id)->delete(); This also doesn't work
            });
        }
    }
    

    您可以使用“每个” http://laravel.com/docs/eloquent#collections

    【讨论】:

    • 我已经尝试过使用每个,但是我认为它与使用 foreach 没有太大不同,您仍然需要遍历每个对象。我更好奇为什么 $entry->options()->delete 不起作用
    【解决方案2】:

    有一个很好的包可以将其作为上述引导方法的替代方法并用于软删除。

    写: https://medium.com/asked-io/cascading-softdeletes-with-laravel-5-a1a9335a5b4d

    Laravel/Lumen 软级联删除和恢复 https://github.com/Askedio/laravel-soft-cascade

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-13
      • 2013-06-19
      • 2015-10-06
      • 1970-01-01
      • 2016-05-13
      • 1970-01-01
      • 2022-11-02
      • 2015-05-14
      相关资源
      最近更新 更多