Laravel Eloquent级联删除

时间:2014-03-28 07:13:07

标签: php laravel-4

我正在使用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中的一个错误还是我犯了错误。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

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

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