Model filters based on the current authenticated user

I am working on an application in which each user is assigned a specific region. For example, user 1 belongs to the Phoenix region, user 2 refers to Scottsdale, and user 3 refers to Tempe. Each user's area is defined in the region_id column.

The application has 3 separate defenders for 3 different user models (this is a base with regional managers, suppliers and customers). Almost every application model has a region_id column that determines which region the resource belongs to.

I would like to simplify the process of requesting resources. I am currently filtering each model / resource directly in the controller, for example:

$customers = Customer::where('region_id', Auth::user()->region_id); 

I would like to set such filters on a global level so that each authenticated user can see entries only from their region. It is especially important to display a list of records in the current region, rather than checking if the user can access / edit a single record.

I looked at Query Scopes , but I cannot access an authenticated user. The only case where I can access the current user is when the global region is defined in the closure, but this defeats the goal of not defining the same logic in each model (i.e. I can’t extract the filtering logic into the request region class )

What would be a good alternative approach? How to set global model filters based on the properties of the currently authenticated user?

0
php laravel laravel-5
source share
2 answers

I had a similar question as a possible error (I was not sure if this behavior was expected) on the Laravel Framework tracker on GitHub and found the answer there.

It turns out that you cannot access the authenticated user in the global designer of the request scope, but it is available in the apply () method.

So, instead of:

 public function __construct() { $this->region_id = Auth::user()->region_id; } public function apply(Builder $builder, Model $model) { $builder->where('region_id', $this->region_id); } 

I had to do:

 public function apply(Builder $builder, Model $model) { $region_id = Auth::user()->region_id; $builder->where('region_id', $region_id); } 

Link to the GitHub question here .

0
source share

How to make RegionalModel and extend all your Models with the region_id field? Then, in RegionalModel create a scope such as forUser(User $user) to apply the filter.

 class RegionalModel extends Model { public function scopeForUser($query, User $user) { // Apply filter here } } 

Then your client model might look like this:

 class Customer extends RegionalModel { // Code here } 

Then when you want to get a list of customers

 $user = Auth::user(); $customers = Customer::forUser($user)->get(); 
+1
source share

All Articles