我们在使用带有动态查询参数的全局作用域时遇到了问题。全局作用域是基于管理器ID的,但是$model是空的,而且$this指的是管理器作用域而不是模型,所以$this-> ID是一个未定义的属性。有没有办法这样做:
public function apply(Builder $builder, Model $model)
{
return $builder->where('manager', $model->id); // $this->id
}
我假设$model
应该是经理模型,但由于它是空的,我找不到任何关于它的文档,我不完全确定(如果有人能在评论中告诉我,我会很感激)。这是我们在Manager模型中的全局作用域方法:
protected static function boot()
{
parent::boot();
static::addGlobalScope(new ManagerScope);
}
由于全局作用域不需要显式方法,我想也许可以添加一些东西到引导可能允许一个额外的参数,如:
protected static function boot()
{
parent::boot();
static::addGlobalScope(new ManagerScope($this->id);
}
但是这在静态方法中是不允许的,这在我看到错误后是有意义的。
全局作用域自然是自动应用的,没有办法直接向它们传递参数。
因此,您可以坚持使用动态局部作用域,这在我看来更有意义,
public function scopeForManager($query, $manager)
{
return $query->where('manager', $manager->id);
}
Document::forManager($manager)->all();
或者如果管理器信息在某种全局状态(即会话)中可用,则可以创建某种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());
}
}
并将其实例传递到
作用域protected static function boot()
{
parent::boot();
static::addGlobalScope(new ManagerScope(new ManagerResolver());
}
更新Laravel 8.x
您可以在模型中创建一个静态函数,然后在创建的作用域中使用它。例如,假设您想要为所有表创建一个全局搜索,而不是为每个模型创建一个搜索函数。
在作用域类中执行以下操作:
<?php
namespace App'Scopes;
use Illuminate'Database'Eloquent'Builder;
use Illuminate'Database'Eloquent'Model;
use Illuminate'Database'Eloquent'Scope;
class SearchScope implements Scope
{
/**
* Apply the scope to a given Eloquent query builder.
*
* @param 'Illuminate'Database'Eloquent'Builder $builder
* @param 'Illuminate'Database'Eloquent'Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
if(!empty($keyword = 'request()->query('q')))
$builder->where($model::searchField(), 'LIKE', '%' . $keyword . '%');
}
}
然后在每个模型中创建searchField()函数,像这样:
<?php
namespace Modules'Api'Models;
use Illuminate'Database'Eloquent'Model;
use App'Scopes'SearchScope;
class Product extends Model
{
protected static function searchField(){
return "products.name"; // Name of field to be used in WHERE clause while searching using LIKE operator
}
protected static function booted()
{
static::addGlobalScope(new SearchScope);
}
}
万岁!现在你可以在Laravel作用域中使用动态变量了!!