如何使策略自动发现新 Laravel 功能与我在不同文件夹中的模型一起使用?

How to make Policy Auto-Discovery new Laravel feature work with my models in a different folder?

我刚刚将我的 Laravel 更新到 5.8,但无法使我的策略自动发现工作。

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

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

但我做不到。检查函数 '''$user->can()''' 对于我所有的策略和模型总是 return false。 真的是问题所在吗? models 文件夹,还是我遗漏了 somenting?

顺便说一句,如果我在 $policies 数组中手动​​将其映射到 AuthServiceProvider.php[=,一切都会很好12=]

谢谢!

如果有人有这个问题,我是这样纠正的。

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

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

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

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

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

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

以防万一有人像我一样更改了 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 名称路径,所以我所做的是创建一个常量变量 APP_FOLDER,其中包含应用程序文件夹名称的字符串和我可以在使用 app()::APP_FOLDER.

的任何地方调用它

即如果你有一个模型 MyApp\Models\Core\User 猜测策略名称将是 MyApp\Policies\Models\Core\User.

如有任何疑虑,请随时问我,希望这也能有所帮助。

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