如何使Policy Auto-Discovery新的Laravel功能与其他文件夹中的模型一起使用?

时间:2019-03-31 13:17:10

标签: php laravel-5.8

我刚刚将Laravel更新为5.8,无法使我的政策自动发现。

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

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

但是我无法使其工作。对于我的所有策略和模型,检查函数'''$ user-> can()'''始终返回false。 真的有问题吗?是“ models”文件夹,还是我想念呢?

顺便说一句,如果我在 AuthServiceProvider.php

$ policies 数组中手动​​将其映射,则一切工作都很好。

谢谢!

2 个答案:

答案 0 :(得分:3)

如果有人遇到此问题,这是我的纠正方法。

原来是App/Models结构是问题所在。 laravel通过 magic 猜测策略名称考虑了模型的位置。

要绕过此行为,请将代码放在引导功能的app/Providers/AuthServiceProvider.php内部。

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

它将强制查看App/Policies而不是App/Models/Policies。 (相应更改)

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

再见,希望以后能帮助别人。

答案 1 :(得分: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

I.E。如果您有模型MyApp\Models\Core\User,则猜测策略名称将为MyApp\Policies\Models\Core\User

任何担忧都可以随时向我询问,我希望这也能有所帮助。

PS:我使用了PHP v7.2.9Laravel v5.8.37