Symfony2 形式的交叉引用无法按预期工作
这是我的第一个问题,所以请原谅任何错误 - 下次我会尽力避免它们。 ;-)
我已经为 FOSUserBundle 编写了一个自定义的 RegistrationFormType。除了捆绑包的默认字段之外,此表单还处理 PlayerType。此 PlayerType 本身再次包含 PlayerSkillsType。这里是类:(
class RegistrationFormType extends BaseType
{
public function buildForm(FormBuilder $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('player', new PlayerType());
}
public function getName()
{
return 'signup_form';
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Acme\AcmeBundle\Entity\User',
);
}
}
class PlayerType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('firstname');
$builder->add('lastname');
$builder->add('age');
$builder->add('playerSkills', new PlayerSkillsType());
}
public function getName()
{
return 'player_form';
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Acme\AcmeBundle\Entity\Player',
);
}
}
class PlayerSkillsType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('tackling');
$builder->add('passing');
$builder->add('shooting');
}
public function getName()
{
return 'playerSkills_form';
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Acme\AcmeBundle\Entity\PlayerSkills',
);
}
}
/**
* @ORM\Entity
*/
class Player
{
/**
* @ORM\OneToOne(targetEntity="PlayerSkills", cascade={"persist"})
*
* @var PlayerSkills
*/
private $playerSkills;
}
/**
* @ORM\Entity
*/
class PlayerSkills
{
/**
* @ORM\OneToOne(targetEntity="Player", cascade={"persist"})
*
* @var Player
*/
private $player;
}
我省略了 getter 和 setter 以及不重要的属性和方法。) 到目前为止,这工作正常,表单已显示并保留。现在,我的问题是,在保存数据后,数据中的 PlayerSkills 实体缺少对 Player 实体的引用。
我认为我需要告诉 PlayerSkillsType 它还应在表单生成器中添加引用..?或者这可能是教义注释中的问题?
任何提示都非常感谢! :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题可能来自数据和/或学说映射的初始化。
如果使用
$form->setData
未传递任何数据,则表单将创建 data_class。当你提交表单并绑定数据时,它会调用
$player>setPlayerSkills($playerSkill)
,但它不会调用 $playerSkill->setPlayer($player);
根据 oneToOne 关联的拥有方,您应该调用这两种方法之一,以便 Doctrine 知道此关联( http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/association-mapping.html#owning-side-and-inverse-side ).
尝试修改 PlayerSkills 中的注释映射以引入
inversedBy
信息 ( http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/association-mapping.html#one-to-one-bidirection ) 。它应该是这样的:
Player 类也是如此:
最后,您可以编写方法来自动同步反面,如下所述: http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/association-mapping.html#picking-owning-and-inverse-side .
The problem could come from the initialization of your data and/or doctrine mapping.
The form will create the data_class if none is passed using
$form->setData
.When you submit the form and bind data, It will call
$player>setPlayerSkills($playerSkill)
,but it won't call $playerSkill->setPlayer($player);
Depending of the owning side of your oneToOne association, you should call one of the two methods so that Doctrine will be aware of this association ( http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/association-mapping.html#owning-side-and-inverse-side ).
Try to modify your annotation mapping in PlayerSkills to introduce the
inversedBy
information also ( http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/association-mapping.html#one-to-one-bidirectional ).It should be something like this:
Same thing for the Player class:
Last, you can code your methods to automatically synchronize inverse side, as explained here: http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/association-mapping.html#picking-owning-and-inverse-side .