我正在开发一个应用,其中为每个用户分配了一个特定的区域。例如,用户1属于区域'Phoenix',用户2属于'Scottsdale',用户3属于'Tempe'。每个用户的区域在region_id列中定义。
该应用程序有3个独立的警卫,可用于3种不同的用户模型(这是一个有区域经理,提供商和客户的市场)。实际上,应用程序中的每个模型都有一个region_id列,用于标识资源所属的区域。
我想简化查询资源的方式。目前,我正在控制器中直接过滤每个模型/资源,例如:
$customers = Customer::where('region_id', Auth::user()->region_id);
我想在全局级别设置此类过滤器,以确保每个经过身份验证的用户只能从自己的区域查看记录。特别是对于显示当前区域中的记录列表而不是检查用户是否可以访问/编辑特定的单个记录非常重要。
我已查看Query Scopes,但我无法使用它们访问当前经过身份验证的用户。我可以访问当前用户的唯一情况是在闭包中定义全局作用域时,但是这样做的目的就是不必在每个模型中定义相同的逻辑(即,我无法将过滤逻辑提取到查询作用域类中)。
考虑什么是一个好的替代方法?如何根据当前经过身份验证的用户的属性设置全局模型过滤器?
答案 0 :(得分:1)
如何制作RegionalModel
并将所有Models
扩展为region_id
字段?然后,在RegionalModel
中创建一个类似forUser(User $user)
的范围,以应用您的过滤器。
class RegionalModel extends Model {
public function scopeForUser($query, User $user) {
// Apply filter here
}
}
然后您的客户模型可能如下所示
class Customer extends RegionalModel {
// Code here
}
然后当您想获得客户列表时
$user = Auth::user();
$customers = Customer::forUser($user)->get();
答案 1 :(得分:0)
我在GitHub上的Laravel Framework问题跟踪器上发布了一个类似的问题作为可能的错误(不确定这种行为是否符合预期)并在那里找到答案。
事实证明,您无法在全局查询范围构造函数中访问经过身份验证的用户,但可以在apply()方法中访问它。
所以而不是:
public function __construct() {
$this->region_id = Auth::user()->region_id;
}
public function apply(Builder $builder, Model $model)
{
$builder->where('region_id', $this->region_id);
}
我必须这样做:
public function apply(Builder $builder, Model $model)
{
$region_id = Auth::user()->region_id;
$builder->where('region_id', $region_id);
}
链接到GitHub上的问题here。