【发布时间】:2021-04-29 12:49:07
【问题描述】:
我有一个关于 Cake 对使用下划线名称命名的模型/实体的政策进行烘焙的问题。
我有一个使用身份验证和授权中间件的应用程序,但是在具有 two_word 名称的模型上烘焙实体和表的授权策略不会生成正确的代码(在我看来)。
我将尝试通过在我的应用中创建的一个基本示例来简化问题,以重现问题:
-
首先,我正在使用: CAKE_VERSION:4.2.5, cakephp/认证:2.0, cakephp/授权:2.0, php: >=7.2, (另外,我在 Windows 10 上运行 XAMPP)
-
我在我的应用中创建了这两个简单的模型来演示这个问题:
CREATE TABLE `dogs` (
`id` int(11) NOT NULL,
`name` varchar(16) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=tis620;
与
CREATE TABLE `dog_traits` (
`id` int(11) NOT NULL,
`dog_id` int(11) NOT NULL,
`trait` varchar(128) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=tis620;
- 我为这两个模型烘焙了所有内容:
bin\cake bake all dogs
bin\cake bake policy --type entity dog
bin\cake bake policy --type table dogs
与
bin\cake bake all dog_traits
bin\cake bake policy --type entity dog_trait
bin\cake bake policy --type table dog_traits
- 对于 Dogs 模型,一切正常。 Dog 政策如下所示:
declare(strict_types=1);
namespace App\Policy;
use App\Model\Entity\dog;
use Authorization\IdentityInterface;
class dogPolicy
{
/**
* Check if $user can create dog
*
* @param Authorization\IdentityInterface $user The user.
* @param App\Model\Entity\dog $dog
* @return bool
*/
public function canCreate(IdentityInterface $user, dog $dog)
{
if ($user) {
return true;
}
return false;
}
// Etc....
}
然后在 Dogs 控制器中:
public function add()
{
$dog = $this->Dogs->newEmptyEntity();
$this->Authorization->authorize($dog, 'create');
if ($this->request->is('post')) {
//Etc....
这按预期工作,没问题。
- 但是,对于我所有名称带有下划线的模型(例如 dog_traits),烘焙策略似乎无法正常工作。
这是默认烘焙的
DogTraitPolicy.php的样子:
declare(strict_types=1);
namespace App\Policy;
use App\Model\Entity\dog_trait;
use Authorization\IdentityInterface;
class dog_traitPolicy
{
/**
* Check if $user can create dog_trait
*
* @param Authorization\IdentityInterface $user The user.
* @param App\Model\Entity\dog_trait $dogTrait
* @return bool
*/
public function canCreate(IdentityInterface $user, dog_trait $dogTrait)
{
if ($user) {
return true;
}
return false;
}
//ETC....
}
然后在 DogTraits 控制器中:
public function add()
{
$dogTrait = $this->DogTraits->newEmptyEntity();
$this->Authorization->authorize($dogTrait, 'create');
if ($this->request->is('post')) {
//Etc....
所以现在 URL http://localhost/myapp/dog-traits/add 抛出错误:
Policy for App\Model\Entity\DogTrait has not been defined.
如果我返回 DogTraitPolicy.php 并将类名更改为 dogTraitPolicy 类(驼峰式而不是下划线),我会收到错误消息:
Argument 2 passed to App\Policy\dogTraitPolicy::canCreate() must be an instance of App\Model\Entity\dog_trait, instance of App\Model\Entity\DogTrait given, called in C:\xampp\htdocs\myapp\vendor\cakephp\authorization\src\AuthorizationService.php on line 93
如果我将 canCreate 方法更改为此(注意驼峰式参数名称):
public function canCreate(IdentityInterface $user, dogTrait $dogTrait)
{
if ($user) {
return true;
}
return false;
}
然后这会返回错误:
Argument 2 passed to App\Policy\dogTraitPolicy::canCreate() must be an instance of App\Policy\dogTrait, instance of App\Model\Entity\DogTrait given, called in C:\xampp\htdocs\myapp\vendor\cakephp\authorization\src\AuthorizationService.php on line 93
如果我在 $dogTrait 之前删除参数名称 dogTrait,则策略按预期授权。
public function canCreate(IdentityInterface $user, $dogTrait)
{
if ($user) {
return true;
}
return false;
}
所以问题是:实体策略烘焙对于带下划线的模型名称是否正常工作?对于单字模型,它开箱即用,但不适用于 underscored_names。我错过了什么吗?
提前感谢您的任何建议。
【问题讨论】:
-
重新开始并坚持naming conventions,即类名中的单词以大写字符开头并用大写字符分隔,而不是下划线,例如为
Dog、Dogs、DogTrait烘焙,和DogTraits,这些名称将正确映射到带下划线的数据库表名称。 -
谢谢 ndm... 我正在使用带下划线的数据库表名进行烘焙。使用 CamelCased 类名重置和重新烘焙适用于我的问题中的这两种情况。谢谢!
-
这里只是一个观察...如果您使用原始 table_name 烘焙“所有”(用于模型、控制器等),那么 bake 会自动创建所有具有常规类名的类,正确大小写.但是烘焙策略不会自动执行此操作,因此应该使用正确大小写的计划类名称进行烘焙。无论如何......一切都很好,再次感谢。