首页 > 解决方案 > 如何暂时关闭 laravel 垃圾过滤器?

问题描述

假设我有一个 A,它有一个 B,有一个 C 有一个 D。我想从 A 转到 D,但是任何一个(或所有)对象都可能已被删除。所以我必须这样做:

$d = $a->b()->withTrashed()->first()->c()->withTrashed()->first()->d()->withTrashed()->first()

这太可怕了。我真的更愿意这样做:

turnOffTrashedFilter();
$d = $a->b->c->d;

laravel有这样的能力吗?

请注意,这只是一个示例 - 提示此问题的情况实际上要复杂得多,各种调用嵌套在其他调用中,因此实际上不可能像上面那样使用 withTrashed。我需要在请求期间关闭过滤器,而无需修改大量代码来合并两个并行路径。

标签: laravellaravel-5soft-delete

解决方案


没有内置,但可以做到

没有内置方法可以禁用自动软删除过滤。但是,这是可能的。软删除过滤器是一个全局范围,添加到类的引导方法中。它可以像这样删除:

    \Event::listen('eloquent.booted:*', function($name) {
    $name = substr($name, 17); // event name is "eloquent.booted: some/class"
    $class = new \ReflectionClass($name);
    $prop = $class->getProperty('globalScopes');
    $prop->setAccessible(true);
    $scopes = $prop->getValue();
    foreach ($scopes as $c => &$s) {
        unset($s['Illuminate\Database\Eloquent\SoftDeletingScope']);
    }
    $prop->setValue($scopes);
});

这与引导事件挂钩,该事件在全局范围添加到类后立即触发。然后它打开(私有静态)属性 globalScopes,它是附加的全局范围的列表,并删除软删除。这将防止 softdelete 范围附加到任何模型,前提是在添加事件侦听器后调用它们的静态引导方法。


推荐阅读