我已经开始使用Symfony2和MongoDB(Doctrine ODM),并且很难获得唯一的验证器约束来处理多个字段(一个字段使用DBRef引用另一个MongoDB文档)。在我的validation.yml文件中,我有:
Acme\SomeBundle\Document\ArticlePosition:
constraints:
- Doctrine\Bundle\MongoDBBundle\Validator\Constraints\Unique:
fields: [position, section]
“position”字段是一个整数,“section”是一个referenceOne字段,它指向另一个bundle中的实体。
当我为此提交表单时,我在分析器中看到以下查询:
db.article_position.find({ "position": 1, "section": "51ff78494fae886b1f7c0f1d" });
db.article_position.insert({ "000000005dc659f30000000082e5d25d": { "_id":ObjectId("5203d1804fae880e801fd12d"), "position": 1, "section": { "$ref": "section", "$id": ObjectId("51ff78494fae886b1f7c0f1d"), "$db": "my_db" } } });
Symfony / Doctrine似乎正在努力做正确的事情。第一个find()查找包含位置和节字段的匹配文档,但是它缺少DBRef字段($ ref,$ id,$ db)并且总是返回一个空集。
find()查询应该是这样的:
db.article_position.find({ "position": 1, "section": { "$ref": "section", "$id": ObjectId("51ff78494fae886b1f7c0f1d"), "$db": "my_db" }});
我的学说YAML文件如下:
Acme\SomeBundle\Document\ArticlePosition
type: document
collection: article_position
referenceOne:
section:
targetDocument: Acme\SomeOtherBundle\Document\Section
fields:
id:
type: id
id: true
position:
type: int
部分文档位于与ArticlePosition文档不同的捆绑包中。
答案 0 :(得分:2)
这更像是一种解决方法而非解决方案。
首先,在您的控制器中,您必须在调用$ form-> isValid()之前手动将部分链接到ArticlePosition。
$entity = new ArticlePosition();
$entity->setSection($section);
...
$form->handleRequest($request);
if ($form->isValid()) {
...
}
其次,您必须为Unique约束指定自定义存储库方法。
# validation.yml
Acme\DefaultBundle\Document\ArticlePosition:
constraints:
- Doctrine\Bundle\MongoDBBundle\Validator\Constraints\Unique:
fields: [section, position]
repositoryMethod: findUniqueBy
并在您的ArticlePositionRepository
中public function findUniqueBy($criteria)
{
$section = $criteria['section'];
$position = $criteria['position'];
return $this->findBy(array('section.id' => $section, 'position' => $position));
}
关键是在findBy中为Mongodb添加.id以正确查询结果。