这是一个如此微不足道的问题,我不敢相信我找不到答案。
Symfony 2,原则 2.1。我有两个实体和一个中间实体(连接表)。用户、首选项和用户首选项。首选项表是字典表,因此我只能在一处更改首选项名称。好吧,我们看图:
信息图http://dl.dropbox.com/u/22495762/infographic.png
如您所见,我想要一个复选框组,其中选中所有可能的选择(首选项)和首选选项。因此,如果有 3 个首选项,并且用户只选择了 2 个,则应该有 3 个复选框,其中选择了 2 个。
这很简单,如果用纯 PHP 完成 - 查询数据库两次以获取所有首选项和用户首选项的列表,根据值呈现复选框,添加一些操作来处理表单提交,完成。
但看在上帝的份上,我无法使用 symfony 和教义来实现这一点。我能够达到可以更新学说中的关系并进一步更新数据库中的关系的程度,但我为此使用原始查询值:
$data = $request->request->get('some_form');
这应该不是应该做的事情吗?
更重要的是,我完全不知道应该如何显示复选框列表。我要么获取所有选项的列表,未选中任何选项,要么仅获取用户选项,全部选中。或者“左连接”结果集,在所有情况下都带有复选框,无论如何都没用。
我已经到了尝试重载 twig 复选框模板的地步,但我无法将变量传递给表单模板,这是最后一根稻草......
编辑:
这样我就可以得到一组复选框,而不与用户选择相关:
->add('prefs', 'entity', array(
'class' => 'Some\TestBundle\Entity\Pref',
'expanded' => 'true',
'multiple' => 'true',
'property' => 'name'
))
这样我只能得到用户的选择,全部选中:
->add('prefs', 'entity', array(
'class' => 'Some\TestBundle\Entity\UserPrefs',
'multiple' => 'false',
'expanded' => 'false',
'property' => 'pref.name',
'query_builder' => function(EntityRepository $er) use ($id) {
return $er->createQueryBuilder('u')
->where("u.user = :id")
->setParameter('id', $id)
;
},
))
我尝试了左连接和其他选项,但最多我可以得到所有可能用户的所有可能选项的列表,并进行相应的检查。
我正在显示复选框组:
->add('pref_ids', 'choice', array(
'choices' => array(
'1' => 'pref one',
'2' => 'pref two',
'3' => 'pref three',
),
'expanded' => 'true',
'multiple' => 'true'
))
我在用户实体中添加了
$pref_ids
数组。现在我只需要根据用户选择的偏好设置数组中的值:
public function setPrefIds()
{
$prefs = $this->getPrefs();
$this->pref_ids = array();
foreach($prefs as $pref){
array_push($this->pref_ids, $pref->getPref()->getId());
}
return $this;
}
这样我就可以选中适当的复选框。
将值写入数据库是该过程的逆过程。我从请求中获取输入值:
$data = $request->request->get('edit_form');
var_dump($data['pref_ids']);
删除所有用户首选项:
foreach ($userPrefs as $pref){
$em->remove($pref);
}
并根据 ids 设置教义中的实际关联:
$entity->setPrefsById($em, $data['pref_ids']);
这里我将实体管理器传递给实体本身,但我需要重构它,因为这样看起来有点混乱。
然后
$em->flush();
就这样了。
这是我能想到的最好的办法了。可能它过于复杂,应该以完全不同的方式完成。不幸的是无法弄清楚这个“其他方式”。
您需要选择字段类型:http://symfony.com/doc/current/reference/forms/types/choice.html
在你的构建器中,它会是这样的
$builder->add('prefs', 'choice', array('multiple' => true, 'expanded' => true, 'choices' => fetch the available prefs from the database here);
编辑:抱歉我错了,您需要“实体”类型,它会自动从数据库中获取选择:http://symfony.com/doc/current/reference/forms/types/entity.html
您仍然必须放置多个 => true Expanded => true 才能获取复选框。