我已定义用户实体(以yml映射)
namespace My\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class User
{
...
我创建了一个继承自该实体的子类,以便我可以添加一些自定义验证方法和一些我需要但不需要保留的字段(例如ConfirmPassword,ConfirmEmail字段)
namespace My\SecondBundle\EditModels;
use My\CoreBundle\Entity\User;
class UserModel extends User
{
当用户提交注册表单时,我将请求映射到UserModel实体,如果它是有效的,我会尝试保留用户。
以下代码抛出异常
$entityManager->persist($userModel);
//=>The class 'My\SecondBundle\EditModels\UserModel' was not found in the chain configured namespaces My\CoreBundle\Entity
问题:如何将$ userModel(UserModel的实例)作为User实体类持久化?可能的选择:
我不认为我应该使用Doctrine继承机制,因为我不想保存额外的字段。
谢谢
答案 0 :(得分:0)
我认为您的问题在于,您刚刚在Doctrine2中配置了My\CoreBundle\Entity
命名空间,但您实际想要保留的实体位于My\SecondBundle\EditModels
。
通常在继承标记为@ORM\Entity()
的类时,您要扩展的类必须具有类注释@ORM\MappedSuperclass()
。但通常你会将它用于单表不一致,例如,不是用于你的用例。
在我看来,将数据库相关属性与其他属性分开的方法是不可承受的。我会在模型中保留与验证相关的内容 - 您需要在创建/更新操作中使用它。
我不熟悉XML配置,但在使用注释时,您需要将每个属性标记为与数据库映射(使用@ORM\Column()
)。因此,Doctrine将完全忽略所有其他属性和方法。
所以我在这里分享了我最近开发的AbstractModel,看看我是如何实现验证的(使用respect/validation):
<?php
namespace Vendor\Package\Model;
use Doctrine\ORM\Mapping as ORM;
/**
* Abstract Model
*
* @ORM\MappedSuperclass()
*/
abstract class AbstractModel
{
/**
* @var \Respect\Validation\Validator
*/
protected $validator;
/**
* AbstractModel constructor
*/
public function __construct()
{
$this->validator = static::validation();
}
/**
* Defines validation for this model
*
* @return \Respect\Validation\Validator
*/
public static function validation() : \Respect\Validation\Validator
{
return \Respect\Validation\Validator::create();
}
/**
* Executes validations, defined in validation method.
*
* @return bool
*/
public function isValid() : bool
{
if (is_null($this->validator)) {
$this->validator = new \Respect\Validation\Validator();
$this->validation();
}
return $this->validator->validate($this);
}
}
从AbstractModel扩展的模型需要实现静态验证方法,以定义类验证:
<?php
namespace Vendor\Package\Model;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity()
* @ORM\Table(name="my_model")
*/
class MyModel extends AbstractModel
{
/**
* @var string
* @ORM\Column(type="string")
*/
private $name;
/**
* Defines validation for this model
*
* @return \Respect\Validation\Validator
*/
public static function validation() : \Respect\Validation\Validator
{
return \Respect\Validation\Validator::create()
->attribute('name', \Respect\Validation\Validator::notEmpty()->stringType()->length(null, 32))
;
}
// getter, setter, ...
}
每个实体,持久化到数据库,将具有$validator
属性和所有这些方法,但因为我在这里留下了注释(并且非常确定这也适用于xml / yaml),Doctrine忽略它。
通过这种方式,您还可以将验证相关的东西保留在模型类本身之外,这有利于提高可读性。验证本身应该在模型本身中定义,imho。但是这个尊重/验证框架是实现这一目标的巧妙方法。希望这会有所帮助:)