【问题标题】:Cross reference in Symfony2 form not work as expectedSymfony2 表单中的交叉引用无法按预期工作
【发布时间】:2012-02-11 13:24:37
【问题描述】:

这是我在这里的第一个问题,所以请原谅任何错误 - 下次我会尽量避免它们。 ;-)

我为 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 它还应该在表单构建器中添加引用..?或者这可能是 Doctrine 注释中的问题?

非常感谢任何提示! :-)

【问题讨论】:

    标签: symfony doctrine-orm symfony-forms fosuserbundle


    【解决方案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-bidirectional)。

    应该是这样的:

     /**
     * @ORM\OneToOne(targetEntity="Player", mappedBy="playerSkills", cascade={"persist"})
     *
     * @var Player
     */
    private $player;
    

    Player 类也是如此:

    /**
     * @ORM\OneToOne(targetEntity="PlayerSkills", inversedBy="player" cascade={"persist"})
     *
     * @var PlayerSkills
     */
    private $playerSkills;
    

    最后,您可以编写方法以自动同步反向端,如下所述:http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/association-mapping.html#picking-owning-and-inverse-side

    【讨论】:

    • 非常感谢!你让我今天一整天都感觉很好! ;-)
    猜你喜欢
    • 2023-03-14
    • 2014-12-18
    • 1970-01-01
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多