带有动态参数的 Laravel 5 全局作用域

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39277768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 14:24:11  来源:igfitidea点击:

Laravel 5 Global Scope with Dynamic Parameter

phplaravellaravel-5laravel-5.2

提问by mtpultz

We're having issues using a global scope with a dynamic query parameter. The global scope is based on the manager ID, but $model is empty, and $this refers to the manager scope not the model so $this->id is an undefined property. Is there a way to do something like this:

我们在使用具有动态查询参数的全局范围时遇到问题。全局范围基于管理器 ID,但 $model 为空,并且 $this 指的是管理器范围而不是模型,因此 $this->id 是未定义的属性。有没有办法做这样的事情:

public function apply(Builder $builder, Model $model)
{
    return $builder->where('manager', $model->id); // $this->id
}

I'm assuming that $modelis supposed to be the manager model, but since it is empty and I can't find any documentation on it I'm not entirely sure (if anyone can tell me in a comment I'd appreciate it). This is our global scope method in the Manager model:

我假设这$model应该是经理模型,但由于它是空的,我找不到任何关于它的文档,我不完全确定(如果有人能在评论中告诉我,我会很感激)。这是我们在 Manager 模型中的全局作用域方法:

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

    static::addGlobalScope(new ManagerScope);
}

Since global scopes don't require an explicit method to be applied I thought maybe adding something to the boot might allow for an extra parameter something like:

由于全局作用域不需要应用显式方法,我认为可能在引导中添加一些内容可能会允许一个额外的参数,例如:

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

    static::addGlobalScope(new ManagerScope($this->id);
}

But this isn't allowed in a static method, which makes sense after I saw the error.

但这在静态方法中是不允许的,这在我看到错误后才有意义。

回答by peterm

Naturally global scopes are applied automatically and there are no way to pass parameters to them directly.

自然地,全局作用域是自动应用的,无法直接将参数传递给它们。

Therefore you can either stick with a dynamic local scope, which IMO makes more sense,

因此,您可以坚持使用 IMO 更有意义的动态本地范围,

public function scopeForManager($query, $manager)
{
    return $query->where('manager', $manager->id);
}

Document::forManager($manager)->all();

or if the a manager info is available in some kind of global state (i.e. session) you can create some sort of ManagerResolver class

或者如果管理器信息在某种全局状态(即会话)中可用,您可以创建某种 ManagerResolver 类

class ManagerScope
{
    protected $resolver;

    public function __construct(ManagerResolver $resolver)
    {
        $this->resolver = $resolver
    }

    public function apply(Builder $builder, Model $model)
    {
        return $builder->where('manager', $this->resolver->getManagerId());
    }    
}

and pass an instance of it into your scope

并将它的一个实例传递到您的作用域中

protected static function boot()
{
    parent::boot();
    static::addGlobalScope(new ManagerScope(new ManagerResolver());
}