Laravel 5.8: Как разрешить auth () -> user () в методе применения Global Scope? - PullRequest
1 голос
/ 07 июня 2019

Мне нужно применять определенную глобальную область, только если роль аутентифицированного пользователя чем-то равна.Таким образом, этот пользователь с определенной ролью сможет выполнять запросы только для данного подмножества записей.

Я могу легко иметь дело с моделью пользователя (в настоящее время вошел в систему пользователя), но не в методе применения области действия.

https://github.com/laravel/framework/issues/22316#issuecomment-349548374

Конструктор области выполнения выполняется очень рано, до того, как промежуточное ПО аутентификации запустит .Разрешить пользователя в методе применения, а не в конструкторе.

ОК, поэтому я нахожусь внутри метода apply:

<?php

namespace App\Scopes;

use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class UserScopeForSalesContactAdmin implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $builder
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        dd('within apply', auth()->user());
        dd(auth()->user()); // won't work

        $builder->where('foo', '=', 'something from currently logged in user');
    }
}

Очевидно, второе dd дает:

Достигнут максимальный уровень вложенности функций '512', прерывание!

Как решить эту проблему?Я полагаю, что должен вызывать контейнер IOC через app()->make(), но потом?

Спасибо за любые подсказки.

edit: Я думаю, что вижу причину бесконечного цикла (https://github.com/laravel/framework/issues/26113), ноТем не менее мне нужно найти лучший способ получить пользователя ...

1 Ответ

0 голосов
/ 08 июня 2019

Проблема здесь в том, что вы определяете область действия для пользователя, при извлечении пользователя с помощью Auth :: user () он снова будет использовать область действия до того, как будет решен первый вызов метода, и оттуда у нас есть StackOverflow. Я думаю, что есть умный подход, перезаписывающий охрану и сохраняющий пользовательскую модель в классе, который вы можете получить оттуда, но я также не фанат настройки со встроенными Laravel функциями.

Простым подходом может быть использование Auth :: id и получение нужной информации с помощью DB :: table, это не красиво, но я думаю, что это прямой подход к решению проблемы.

public function apply(Builder $builder, Model $model)
{
    // this will not trigger the scope when you fetch it out again, and avoiding the stackoverflow
    $user = DB::table('users')->where('id', Auth::id())->get()->first();

    $builder->where('foo', '=', $user['the_answer_to_life']);
}
...