您要完成的是为当前用户提交的表单中的每个问题创建一个 Score 对象。
为此,首先为 Score 对象创建一个表单类型。
<?php
// src/Acme/Bundle/Form/Type/ScoreType.php
// ...
$builder->add('ranking', 'integer')
这将允许您的应用程序通过表单创建分数对象。
现在,在您的问题表单类型中,您需要嵌入一个非映射的分数表单(原因如下所述),即。
<?php
// src/Acme/Bundle/Form/Type/QuestionType.php
// ...
$builder->add('question')
$builder->add('score', new ScoreType(), array('mapped'=>false))
我假设您目前有一个与此类似的设置,除了您可能在“分数”上使用带有 ScoreType 的集合类型。但是,如果此表单旨在供当前用户查看,那么您将不会想要显示集合。您宁愿只显示一个,即附加到当前用户的那个。Symfony 无法知道这个逻辑,因为它是特定于您的业务逻辑的。
这是事件的来源。请参阅http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
我的方法是将 EventSubscriber 绑定到 Question 表单。您可能应该听 PRE_SET_DATA 事件和 SUBMIT 事件。
您的 PRE_SET_DATA 侦听器应检查传入的 Question 对象以获取有关应将什么分数放入“分数”表单的信息。例如,如果实体管理器被注入到您的订阅者中,您可能会询问 EM,该用户是否已经为该特定问题获得了分数,如果有,则将其作为数据放入“分数”中。如果不是,则创建一个新的空白 Score 对象并将其与此问题和当前用户相关联。
现在,一旦提交了一个表单,就听 SUBMIT 并用 score 对象做一些逻辑。这就是我们不将其映射到问题的原因,因为它是 1:*。我们的表格是 1:1。这些事件是您执行逻辑以建立连接的地方。在 POST_SUBMIT 期间,您可以获取 Score 对象并使用表单数据调用 $score->setQuestion()。
我意识到这是一个有点模糊和有点仓促的答案,但我希望它能引导你朝着正确的方向前进。