原则 2:持久化给定子类的父实体



我定义了一个用户实体(在yml中映射)

namespace MyCoreBundleEntity;
use DoctrineORMMapping as ORM;
class User
{

我创建了一个从该实体继承的子类,以便我可以添加一些自定义验证方法和一些我需要但不需要保留的字段(例如 ConfirmPassword、ConfirmEmail 字段)

namespace MySecondBundleEditModels;
use MyCoreBundleEntityUser;
class UserModel extends User
{

当用户提交注册表单时,我将请求映射到 UserModel 实体,如果它有效,我会尝试保留用户。

以下代码引发异常

$entityManager->persist($userModel);
//=>The class 'MySecondBundleEditModelsUserModel' was not found in the chain configured namespaces MyCoreBundleEntity

问:如何将$userModel(用户模型的实例)保留为用户实体类? 可能的选项:

  • 不要使用继承的类,而是将自定义字段和验证方法添加到 User 实体本身
  • 将字段从用户模型复制到用户实体并保留用户实体

我认为我不应该使用教义继承机制,因为我不想保存多余的字段。

谢谢

我认为您在这里的问题是您刚刚在 Doctrine2 中配置了MyCoreBundleEntity命名空间,但您实际想要保留的实体位于MySecondBundleEditModels中。

通常,在继承标记为@ORMEntity()的类时,要从中扩展的类必须具有类注释@ORMMappedSuperclass()。但通常您将其用于单表固有性,例如,不用于您的用例。

在我看来,将数据库相关属性与其他属性分开的方法负担不起。我会在模型本身中保留与验证相关的东西 - 您在创建/更新操作中需要它。

我不熟悉XML配置,但是在使用注释时,您需要标记要与数据库映射的每个属性(使用@ORMColumn())。因此,教义将完全忽略所有其他属性和方法。

因此,在这里我为您分享我最近开发的AbstractModel,看看我是如何实现验证的(尊重/验证):

<?php
namespace VendorPackageModel;
use DoctrineORMMapping as ORM;
/**
* Abstract Model
*
* @ORMMappedSuperclass()
*/
abstract class AbstractModel
{
/**
* @var RespectValidationValidator
*/
protected $validator;
/**
* AbstractModel constructor
*/
public function __construct()
{
$this->validator = static::validation();
}
/**
* Defines validation for this model
*
* @return RespectValidationValidator
*/
public static function validation() : RespectValidationValidator
{
return RespectValidationValidator::create();
}
/**
* Executes validations, defined in validation method.
*
* @return bool
*/
public function isValid() : bool
{
if (is_null($this->validator)) {
$this->validator = new RespectValidationValidator();
$this->validation();
}
return $this->validator->validate($this);
}
}

从 AbstractModel 扩展而来的模型需要实现一个静态验证方法,以定义类验证:

<?php
namespace VendorPackageModel;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity()
* @ORMTable(name="my_model")
*/
class MyModel extends AbstractModel
{
/**
* @var string
* @ORMColumn(type="string")
*/
private $name;
/**
* Defines validation for this model
*
* @return RespectValidationValidator
*/
public static function validation() : RespectValidationValidator
{
return RespectValidationValidator::create()
->attribute('name', RespectValidationValidator::notEmpty()->stringType()->length(null, 32))
;
}
// getter, setter, ...
}

每个实体,持久化到数据库,将具有$validator属性和所有这些方法,但是因为我在这里留下了注释(并且非常确定这也适用于xml/yaml),Doctrine忽略了它。

这样,您还可以将与验证相关内容排除在模型类本身之外,这有利于可读性。恕我直言,验证本身应该在模型本身中定义。但是这个尊重/验证框架是实现这一目标的巧妙方式。希望这对:)有所帮助

相关内容

  • 没有找到相关文章

最新更新