Я работаю над приложением, в котором каждому пользователю назначается конкретный регион. Например, пользователь 1 относится к региону «Феникс», пользователю 2 – «Скоттсдейл», а пользователю 3 – «Темпе». Область каждого пользователя определяется в столбце region_id.
Приложение имеет 3 отдельных охранника для 3 различных пользовательских моделей (это рынок с региональными менеджерами, поставщиками и клиентами). Практически каждая модель приложения имеет столбец region_id, определяющий, к какой области принадлежит ресурс.
Я хотел бы упростить процедуру запроса ресурсов. В настоящее время я фильтрую каждую модель / ресурс непосредственно в контроллере, например:
$customers = Customer::where('region_id', Auth::user()->region_id);
Я хотел бы установить такие фильтры на глобальном уровне, чтобы каждый проверенный пользователь мог видеть записи только из своего региона. Особенно важно отображать список записей в текущем регионе, а не проверять, может ли пользователь получать доступ к отдельной записи.
Я просмотрел объекты запросов , но я не могу получить доступ к уже прошедшему проверку подлинности пользователю. Единственный случай, когда я могу получить доступ к текущему пользователю, – это когда глобальная область определена в закрытии, но это побеждает цель не определять одну и ту же логику в каждой модели (т.е. я не могу извлечь логику фильтрации в класс области запроса ).
Каким будет хороший альтернативный подход? Как установить фильтры глобальной модели на основе свойства текущего пользователя, прошедшего проверку подлинности?
Как сделать region_id
и расширить все свои Models
с помощью поля region_id
? Затем в вашем forUser(User $user)
создайте область, такую как 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();
Я отправил аналогичный вопрос как возможную ошибку (не был уверен, что это поведение было что-то ожидалось) на трекер Laravel Framework на GitHub и нашел ответ там.
Оказывается, вы не можете получить доступ к аутентифицированному пользователю в глобальном конструкторе области запроса, но он доступен в методе 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 здесь .