6

我刚刚将我的 Laravel 更新到 5.8 并且无法让我的策略自动发现工作。

我认为这是因为我所有的模型都在app/Models中。文档说我可以使用此门更改默认行为。

Gate::guessPolicyNamesUsing(function ($modelClass) {
    // return policy class name...
});

但我不能让它工作。检查函数 '''$user->can()''' 对于我的所有策略和模型总是返回 false。真的是问题吗?模型文件夹,还是我缺少一些东西?

顺便说一句,如果我在AuthServiceProvider.php的$policies数组中手动​​映射它,一切都会很好

谢谢!

4

2 回答 2

21

如果有人有这个问题,这就是我纠正它的方法。

事实证明,App/Models结构是问题所在。laravel 猜测策略名称的神奇之处在于模型的位置

要绕过此行为,请将下面的代码放入app/Providers/AuthServiceProvider.phpboot 函数中。

Gate::guessPolicyNamesUsing(function ($modelClass) {
    return 'App\\Policies\\' . class_basename($modelClass) . 'Policy';
});

它将强制查看App/Policies而不是App/Models/Policies. (相应地改变)

然后我意识到应该在里面分配策略文件夹,App/Models因为它是模型所在的位置,但是嘿,谁知道呢?我想将我的模型放在不同的文件夹中会让我的生活更加艰难。

拜拜,希望以后能帮到人。

于 2019-04-02T03:21:34.803 回答
1

以防万一有人像我一样更改了 App 文件夹名称,您可以使用以下代码:

    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 文件中的应用程序名称路径,所以我所做的是创建一个APP_FOLDER包含应用程序文件夹名称字符串的常量变量,我可以在任何我使用的地方调用它app()::APP_FOLDER

IE 如果您有模型MyApp\Models\Core\User,则猜测策略名称将是MyApp\Policies\Models\Core\User.

如有任何问题,请随时向我询问,我希望这也能有所帮助。

PS:我PHP v7.2.9用过Laravel v5.8.37

于 2020-03-23T15:29:03.023 回答