положение
Пользователь может принадлежать нескольким организациям, связанным через сводную таблицу с именем employees
Модели в игре: User
, Employee
& Organizations
Соответствующие столбцы базы данных:
users
- id
employees
- user_id
- organization_id
organizations
- id
цель
Эффективный способ проверить, если пользователь 1
и пользователь 2
совместно используют хотя бы один organization_id
в таблице employees
UseCase
Конечная точка API /api/v1/user/#
возвращает дополнительные метаданные о пользователе.
Используя policy
, он проверяет, являются ли текущий пользователь и идентификатор пользователя из URL одинаковыми или они оба являются сотрудниками хотя бы в одной организации, organization_id
на данном этапе неизвестно, все важно то, что оно соответствует.
пример A
пользователь A (1
) является сотрудником организации foo (1
)
пользователь B (2
) является сотрудником организационной панели (2
)
Таким образом, таблица
employee имеет следующие записи:
+-----------------+---------+
| organization_id | user_id |
+-----------------+---------+
| 1 | 1 |
| 2 | 2 |
+-----------------+---------+
в этом примере запрос должен вернуть ложный результат, поскольку между пользователем A и B
нет общего
organization_id
пример B
пользователь A (1
) является сотрудником организации foo (1
)
пользователь A (1
) является сотрудником организации foobar (3
)
пользователь B (2
) является сотрудником организационной панели (2
)
пользователь B (2
) является сотрудником организации foobar (3
)
Таблица сотрудников, таким образом, имеет следующие записи:
+-----------------+---------+
| organization_id | user_id |
+-----------------+---------+
| 1 | 1 |
| 2 | 2 |
| 3 | 1 |
| 3 | 2 |
+-----------------+---------+
в этом примере запрос должен возвращать истинный результат, поскольку существует общий organization_id
между пользователем A и B
код политики
/**
* 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
}
}
код, который работает, но не выглядит эффективным
foreach ($user->organizations()->with('users')->get() as $organization) {
if ($organization->users->where('id', $model->id)->first()) {
return true;
}
}
return false;
экспериментальный код с соединениями вместо того, что делается с моделями Laravel
\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()
запрошенное решение
Эффективный запрос для получения (преобразуемого) логического результата, независимо от того, используют ли два пользователя по крайней мере один organization_id
в таблице employees
, «бонусные баллы» за использование моделей / построителя запросов laravel.
сноска
Спасибо за чтение, вот картошка: 110