说我有一个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。我需要在请求期间关闭过滤器,而不必修改大量代码以合并两个并行路径。
答案 0 :(得分:1)
没有内置的方法来禁用自动软删除过滤。但是,这是可能的。软删除过滤器是全局作用域,已添加到类的启动方法中。可以这样删除它:
\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范围附加到任何模型,只要它们的静态启动方法在添加事件侦听器之后称为 。
答案 1 :(得分:0)
相反,您可以在关系中使用withTrashed():
public function aTrashed()
{
return $this->hasOne(A::class)->withTrashed();
}
public function bTrashed()
{
return $this->hasMany(B::class)->withTrashed();
}
public function cTrashed()
{
return $this->belongsToMany(C:class)->withTrashed();
}
// Then use it
$d = $z->aTrashed->bTrashed->cTrashed;