Doctrine 2、Symfony 2 中的独特约束 [英] Unique Constraints in Doctrine 2, Symfony 2

查看:18
本文介绍了Doctrine 2、Symfony 2 中的独特约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的 Doctrine 2 实体中创建一个唯一约束,使得 name &test 是唯一的列明智的.含义

  • obj1

    • 名称:name1
    • 测试:测试
  • obj2

    • 名称:name2
    • 测试:测试<----重复

这应该会在重复测试时触发错误.

我尝试使用唯一约束(SymfonyBridgeDoctrineValidatorConstraintsUniqueEntity).试过

 * @UniqueEntity("name")* @UniqueEntity("测试")

 * @UniqueEntity({"name", "test"})

当我同时拥有两个名称和测试时,两者似乎只会触发错误.例如.

  • obj1

    • 名称:name1
    • 测试:测试
  • obj2

    • 名称:name2
    • 测试:测试

正确的设置是什么?或者我可能在某个地方犯了错误?

也许我应该包括这样的教义注释:

@Table(name="ecommerce_products",uniqueConstraints={@UniqueConstraint(name="search_idx", columns={"name", "email"})})

但我认为这仍然无法处理我的 symfony 表单验证?

更新

我的测试代码:

/*** @ORM实体* @ORMTable(name="角色")* @UniqueEntity("姓名")* @UniqueEntity("测试")*/类角色{/*** @var 整数* @ORMColumn(type="整数")* @ORMId* @ORMGeneratedValue*/受保护的 $id;/*** @var 字符串** @ORMColumn(type="string", length=32, unique=true)* @AssertMaxLength(32)* @AssertRegex("/^[a-zA-Z0-9_]+$/")*/受保护的 $name;}$v = $this->get('validator');$role = new Role();$role->setName('jm');$role->setTest('test');$e = $v->validate($role);回声'=== 1 ===;var_dump($e);如果(计数($ e)== 0)$em->persist($role);$role2 = new Role();$role2->setName('john');$role2->setTest('test');$e = $v->validate($role2);回声'=== 2 ===;var_dump($e);如果(计数($ e)== 0)$em->persist($role2);$em->flush();

第一次运行(空表):

=== 1 ===object(SymfonyComponentValidatorConstraintViolationList)#322 (1) {[违规":受保护]=>数组(0){}}=== 2 ===object(SymfonyComponentValidatorConstraintViolationList)#289 (1) {[违规":受保护]=>数组(0){}}

但是我确实在数据库层上收到关于唯一约束的错误.那么我应该如何让验证层工作呢?

解决方案

这些单独检查字段:

@UniqueEntity("name")@UniqueEntity("测试")

也就是说,第一个将在有重复的 name 值时被触发,而第二个 - 当有重复的 test 值时.

如果您希望在 both nametest 包含相同的组合时验证失败,请使用此:

@UniqueEntity({"name", "test"})

对于你想要的第一种方法应该有效——除非你在其他地方做错了.还要尝试清除缓存以确保它不是它的错.

更新

我的建议是关于应用端的验证部分.如果您使用 Doctrine 生成数据库模式,则需要为 每一 列提供 Doctrine 级别的注释——当然,如果您想让它们彼此独立,则:

@Column(type = "string", unique = true)私人 $name;@Column(type = "string", unique = true)私人 $test;

这些方法相互补充 - 不排除.@UniqueEntity 确保重复项甚至不会到达数据库层,而 @Column 确保如果到达,数据库层不会让它通过.>

I want to make a unique constraint in my Doctrine 2 entity such that name & test are unique column wise. Meaning

  • obj1

    • name: name1
    • test: test
  • obj2

    • name: name2
    • test: test <---- duplicated

This should trigger an error as test is duplicated.

I tried using the unique constraint (SymfonyBridgeDoctrineValidatorConstraintsUniqueEntity). Tried

 * @UniqueEntity("name")
 * @UniqueEntity("test")

and

 * @UniqueEntity({"name", "test"})

Both seem to only trigger error when I have BOTH name and test duplicated. eg.

  • obj1

    • name: name1
    • test: test
  • obj2

    • name: name2
    • test: test

Whats the right setup? Or I might have made a mistake somewhere?

Perhaps I should include the doctrine annotation like:

@Table(name="ecommerce_products",uniqueConstraints={@UniqueConstraint(name="search_idx", columns={"name", "email"})})

But that still wont handle my symfony form validation I think?

UPDATE

My test code:

/**
 * @ORMEntity
 * @ORMTable(name="roles") 
 * @UniqueEntity("name")
 * @UniqueEntity("test")
 */
class Role {

    /**
     * @var integer
     * @ORMColumn(type="integer")
     * @ORMId
     * @ORMGeneratedValue
     */
    protected $id;

    /**
     * @var string
     * 
     * @ORMColumn(type="string", length=32, unique=true)
     * @AssertMaxLength(32)
     * @AssertRegex("/^[a-zA-Z0-9_]+$/")
     */
    protected $name;

}

$v = $this->get('validator');

$role = new Role();
$role->setName('jm');
$role->setTest('test');
$e = $v->validate($role);
echo '=== 1 ===';
var_dump($e);
if (count($e) == 0)
    $em->persist($role);            

$role2 = new Role();
$role2->setName('john');
$role2->setTest('test');
$e = $v->validate($role2);
echo '=== 2 ===';
var_dump($e);
if (count($e) == 0)
    $em->persist($role2);

$em->flush();

On first run (empty table):

=== 1 ===object(SymfonyComponentValidatorConstraintViolationList)#322 (1) {
  ["violations":protected]=>
  array(0) {
  }
}
=== 2 ===object(SymfonyComponentValidatorConstraintViolationList)#289 (1) {
  ["violations":protected]=>
  array(0) {
  }
}

But I do get an error on database layer about unique constraint. So how should I get Validation layer working tho?

解决方案

These check for the fields individually:

@UniqueEntity("name")
@UniqueEntity("test")

That is, the first one will get triggered when there is a duplicate name value, while the second one — when there is a duplicate test values.

If you want the validation fail when both name and test contain the same combination, you use this:

@UniqueEntity({"name", "test"})

For what you want the first approach should work — unless you did something wrong somewhere else. Also try to clear the cache to make sure it's not its fault.

UPDATE

What I suggested was about the validation part on the app side. If you generate the database schema using Doctrine, you'll need to supply the Doctrine level annotations for each column — if you want to make them unique independently of each other, of course:

@Column(type = "string", unique = true)
private $name;

@Column(type = "string", unique = true)
private $test;

These approaches complement each other — not exclude. @UniqueEntity makes sure a duplicate doesn't even reach the database layer, while @Column ensures that if it does, the database layer won't let it pass.

这篇关于Doctrine 2、Symfony 2 中的独特约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆