【问题标题】:Doctrine 2: How does UniqueObject validator work?原则 2:UniqueObject 验证器如何工作?
【发布时间】:2015-08-11 14:09:48
【问题描述】:

我对 DoctrineModule (v. 0.8.1) 中的 UniqueObject 验证器有疑问。它总是返回 true 或抛出异常。

我在数据库中有以下结构:

 ______________________________________________
| id | user |      email       |     phone    |
|____|______|__________________|______________|
|  1 |  1   |  test@test.com   | 123456789    |
|____|______|__________________|______________|
|  2 |  2   |  0test@test.com  | 123456789    |
|____|______|__________________|______________|

我的代码:

$em = $this->getServiceLocator()->get('Doctrine\ORM\Entitymanager');
$validator = new \DoctrineModule\Validator\UniqueObject(array(
    'object_manager' => $em,
    'object_repository' => $em->getRepository('Application\Entity\User'),
    'fields' => array('email', 'user'),
    'use_context' => false    // <--- I also tried with true
));

来自文档:

如果您省略 use_context 选项或将其设置为 false,您必须 将包含字段和标识符值的数组传递到 isValid()

所以,我跑了:

$validator->isValid(array('email' => 'test@test.com', 'user' => '1'));

抛出异常:

预期的上下文包含 id

如果我将 use_context 设置为 true

来自文档:

如果你将 use_context 选项设置为 true 你必须通过 fields-values 作为第一个参数和一个包含 标识符值作为第二个参数到 isValid()

然后:

$validator->isValid(array('email', 'user'), array('test@test.com', '1'));

总是返回 true,即使不应该这样做,那是因为 https://github.com/doctrine/DoctrineModule/blob/master/src/DoctrineModule/Validator/UniqueObject.php#L107 这一行返回以下值:

array (size=2)
  'email' => string 'email' (length=5)
  'user' => string 'user' (length=4) 

所以它总是会返回 true,因为没有电子邮件名为“email”的用户。

我的问题是:
这个验证器到底是如何工作的?有没有人可以提供这个验证器的工作示例和用例?

我只是想用它来更新用户的电子邮件,但看起来我需要找到其他方法。

【问题讨论】:

  • 它说它需要一个 id,所以试试这个:$validator-&gt;isValid(array('email' =&gt; 'test@test.com', 'id' =&gt; '1')); 我敢打赌它会工作。
  • @Wilt 是正确的(应该添加一个答案)。 Doctrine 中的 identifiers 是用于唯一引用实体的字段,在大多数情况下,您只有一个标识符 id 因此错误“预期上下文包含 id",其中id 是您缺少的标识符值。

标签: symfony doctrine-orm zend-framework2


【解决方案1】:

在您的数据中,您需要包含要检查唯一性的字段,包括标识符字段。

我引用straight from the documentation

其次,您必须为实体获得的每个标识符传递一个值。

您的标识符列是id,因此您还应该发送一个字段id。您的试验中缺少此字段,因此出现错误消息。

那就试试吧:

$validator->isValid(array('email' => 'test@test.com', 'id' => '1')); 

我敢打赌它会起作用。

【讨论】:

  • 在发布该问题之前,我已尝试使用 id,但它无法正常工作 IMO。或者我不明白这一点。我有实体 usercontact。这是一对多的关系,即一个用户可能有许多 不同 电子邮件。使用您的解决方案,它将始终返回 true,因为它检查记录 id 而它应该检查 user 的 id
  • @user1409508 你不应该用NoObjectExists 代替吗?
【解决方案2】:

您应该设置'use_context' =&gt; true 并仅将一个字段应用于'fields' =&gt; ['email'](如果您愿意,可以省略数组)。验证器在这种组合中正常工作。

我在 ZF3 中的验证配置:

[
    'email' => [
        'required' => true,
        'name' => 'email',
        'validators' => [
            [
                'name' => \DoctrineModule\Validator\UniqueObject::class,
                'options' => [
                    'object_manager' => $om = $this->getObjectManager(),
                    'object_repository' => $om->getRepository(User::class),
                    'target_class' => User::class,
                    'use_context' => true,
                    'fields' => ['email'],
                ],
            ],
        ],
    ]
]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 2013-07-23
    • 2020-06-16
    • 1970-01-01
    • 2018-03-08
    • 2013-09-22
    • 1970-01-01
    相关资源
    最近更新 更多