不使用全局作用域使用 Laravel 的触发器

9

概念问题: 在使用touches属性时,我遇到了一个非常简单的问题,它可以自动更新依赖模型上的时间戳;它确实能够正确地执行此操作,但也应用了全局范围。

有没有办法关闭此功能?或者要求特别的自动touches忽略全局范围?


具体例子: 当更新配料模型时,所有相关的食谱都应该被触发。这个功能很好,但是我们有一个globalScope来根据语言环境分离食谱,在应用touches时也会使用它。


配料模型:

class Ingredient extends Model
{
    protected $touches = ['recipes'];

    public function recipes() {
        return $this->belongsToMany(Recipe::class);
    }

}

食谱模型:

class Recipe extends Model
{
    protected static function boot()
    {
        parent::boot();
        static::addGlobalScope(new LocaleScope);
    }

    public function ingredients()
    {
        return $this->hasMany(Ingredient::class);
    }
}

本地化范围:

class LocaleScope implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        $locale = app(Locale::class);

        return $builder->where('locale', '=', $locale->getLocale());
    }

}
2个回答

28
如果您想明确地避免给定查询的全局作用域,可以使用withoutGlobalScope()方法。该方法接受全局作用域类名作为唯一参数。
$ingredient->withoutGlobalScope(LocaleScope::class)->touch();
$ingredient->withoutGlobalScopes()->touch();

因为您不直接调用touch(),所以在您的情况下需要进行一些额外的工作才能使其正常工作。

您可以在模型$touches属性中指定应该触发更新的关系。这些关系返回查询构建器对象。明白我的意思了吗?

protected $touches = ['recipes'];

public function recipes() {
   return $this->belongsToMany(Recipe::class)->withoutGlobalScopes();
}

如果这会影响你的应用程序的其余部分,只需为触摸创建一个新的关系(呵呵 :)

protected $touches = ['recipesToTouch'];

public function recipes() {
   return $this->belongsToMany(Recipe::class);
}

public function recipesToTouch() {
   return $this->recipes()->withoutGlobalScopes();
}

-3

您可以在模型中定义关系并像以下这样传递参数:

public function recipes($isWithScope=true)
{
    if($isWithScope)
        return $this->belongsToMany(Recipe::class);
    else
        return $this->recipes()->withoutGlobalScopes();
}

然后像这样使用它 recipes->get();recipes(false)->get();


你如何通过 touches 属性传递参数?没有这个关键信息,这不是一个解决方案。 - Nicklas Kevin Frank

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接