#php #laravel-5.8
#php #laravel-5.8
Вопрос:
Я только что обновил свой Laravel до версии 5.8 и не могу заставить автоматическое обнаружение политик работать.
Я думаю, это потому, что все мои модели находятся в приложении / Models. В документации говорится, что я могу изменить поведение по умолчанию с помощью этого элемента управления.
Gate::guessPolicyNamesUsing(function ($modelClass) {
// return policy class name...
});
Но я не могу заставить это работать. Функция проверки «‘$user-> can()»‘ всегда возвращает false для всех моих политик и моделей.
Это действительно проблема? Папка models, или я что-то упускаю?
Кстати, все отлично работает, если я сопоставлю это вручную в массиве $ policies в AuthServiceProvider.php
Спасибо!
Ответ №1:
Если у кого-то есть эта проблема, вот как я ее исправил.
Оказалось, что проблема заключалась в App/Models
структуре. Волшебство, совершаемое laravel для угадывания имени политики, учитывает местоположение модели.
Чтобы обойти это поведение, поместите приведенный ниже код внутрь app/Providers/AuthServiceProvider.php
в функцию загрузки.
Gate::guessPolicyNamesUsing(function ($modelClass) {
return 'App\Policies\' . class_basename($modelClass) . 'Policy';
});
Это заставит смотреть на App/Policies
вместо App/Models/Policies
. (измените соответствующим образом)
И тогда я понял, что папка Policies должна быть размещена внутри App/Models
, потому что именно в ней находится модель, но, эй, кто знает? Я предполагаю, что помещение моих моделей в другую папку усложнит мне жизнь.
Пока, надеюсь помочь кому-нибудь в будущем.
Ответ №2:
На всякий случай, если кто-то изменил имя папки приложения, как это сделал я, вы можете использовать следующий код:
Gate::guessPolicyNamesUsing(function ($modelClass) {
$classDirnameArray = explode('\', str_replace('/', '\', dirname(str_replace('\', '/', $modelClass))));
if ($classDirnameArray[0] === app()::APP_FOLDER) {
$classDirnameArray = array_slice($classDirnameArray, 1);
}
return app()::APP_FOLDER.'\Policies\'. implode("\",$classDirnameArray) . "\" . class_basename ( $modelClass).'Policy';
});
Имейте в виду, что вы, вероятно, изменили путь к имени приложения в Application.php file, итак, что я сделал, так это создал постоянную переменную, APP_FOLDER
которая содержит строку имени папки приложения, и я могу просто вызывать ее везде, где я использую app()::APP_FOLDER
.
Т.е. если у вас есть модель, MyAppModelsCoreUser
предположительное название политики будет MyAppPoliciesModelsCoreUser
.
Любые проблемы, не стесняйтесь спрашивать меня об этом, и я надеюсь, что это тоже может помочь.
PS: Я использовал PHP v7.2.9
и Laravel v5.8.37