situation
User can belong to multiple organizations, linked via a pivot table called employees
Models at play: User
, Employee
& Organizations
Relevant database columns:
users
- id
employees
- user_id
- organization_id
organizations
- id
goal
An efficient way to check if user 1
and user 2
share at least one organization_id
in the employees
table
usecase
Api endpoint /api/v1/user/#
returns additional metadata regarding the user.
Using a policy
, it checks if the current user and the user id from the url are the same, or that they are both employee in at least one organization, the organization_id
is not known at this stage, all that matters is that it matches.
example A
user A (1
) is employee of organization foo (1
)
user B (2
) is employee of organization bar (2
)
employee table thus has the following records:
+-----------------+---------+
| organization_id | user_id |
+-----------------+---------+
| 1 | 1 |
| 2 | 2 |
+-----------------+---------+
in this example the query should return a false result, since there is no shared organization_id
between user A and B
example B
user A (1
) is employee of organization foo (1
)
user A (1
) is employee of organization foobar (3
)
user B (2
) is employee of organization bar (2
)
user B (2
) is employee of organization foobar (3
)
employee table thus has the following records:
+-----------------+---------+
| organization_id | user_id |
+-----------------+---------+
| 1 | 1 |
| 2 | 2 |
| 3 | 1 |
| 3 | 2 |
+-----------------+---------+
in this example the query should return a true result, since there is a shared organization_id
between user A and B
policy code
/**
* Determine whether the user can view the model.
*
* @param \App\User $user
* @param \App\User $model
* @return mixed
*/
public function view(User $user, User $model)
{
if ($user->is($model)) {
return true;
} else {
// check if users share at least one organization
}
}
code that works but does not look efficient
foreach ($user->organizations()->with('users')->get() as $organization) {
if ($organization->users->where('id', $model->id)->first()) {
return true;
}
}
return false;
experimental code with joins instead of something done with laravel models
\Illuminate\Support\Facades\DB::table('employees as auth_employee')
->join('employees as other_employee', 'other_employee.organization_id', '=', 'auth_employee.organization_id')
// ->join('organizations', 'organizations.id', '=', 'organizations.id')
->where('auth_employee.id', 1)
->where('other_employee.id', 2)
->get()
requested solution
An efficient query to get a (castable to) boolean result result wether or not 2 users share at least one organization_id
on the employees
table, 'bonus points' for using the laravel models / query builder.
footer
Thanks for reading, here is a potato: 🥔
Assuming you have a users relationship set up in your Organization
model, you could use the whereHas method:
$user->organizations()->whereHas('users', function ($query) use($model) {
$query->where('users.id', $model->id);
})->exists();