【问题标题】:Sonata Admin embed forms one-to-many does not persistSonata Admin 嵌入表单的一对多不会持续存在
【发布时间】:2013-01-14 22:20:07
【问题描述】:

我一直在尝试在 Sonata Admin Bundle 2.0、Sonata User Bundle 2.0 和 Symfony 2.0.16 中实现嵌入表单(是的,我知道它现在有点老了),在阅读了很多论坛帖子和手册后,我可以实现它......但只是在表单级别,它不能在编辑模式下显示数据,或者在创建模式下持久化。

更明确地说,我正在尝试建立用户实体(来自 Sonata 用户包)与电子邮件实体之间的关系,以一对多的关系(一个用户有很多电子邮件,或者只有一个) .因此,在用户表单中将动态嵌入一个或多个电子邮件表单,这似乎正在工作,但与电子邮件表断开连接。

systemUser 指向表用户。我必须更改它,因为我使用的是 PostgreSQL,并且 word 是保留字。

UserAdmin.php

<?php

class UserAdmin extends Admin
{
    // more code

        $formMapper
            ->with('General')
                ->add('username')
                ->add('email')
                ->add('plainPassword', 'text', array('required' => false))
            ->end()
            ->with('Groups')
                ->add('groups', 'sonata_type_model', array('required' => false))
            ->end()
            ->with('Profile')
                ->add('dateOfBirth', 'date', array('required' => false))
                ->add('firstname', null, array('required' => false))
                ->add('lastname', null, array('required' => false))
                ->add('website', 'url', array('required' => false))
                ->add('locale', null, array('required' => false))
                ->add('timezone', null, array('required' => false))
            ->end()
            ->with('Emails')
                ->add('emails', 'collection', array(
                    'label' => 'Emails',
                    'required' => true,
                    'allow_add' => true,
                    'allow_delete' => true,
                    'by_reference' => false,
                ),
                array(
                    'edit' => 'inline',
                    'inline' => 'table',
                    'sortable' => 'id',
                    'targetEntity'=> 'MyProject\xBundle\Entity\Email',
                    'link_parameters' => array('context' => 'user'),
                )
            )
        ;
    // more code ...
}

User.php

<?php

class User extends BaseUser
{
    /**
     * @var array emails
     */
    protected $emails;

    /**
     * @var string user
     */
    protected $user;


    public function __construct()
    {
        $this->emails = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add emails
     *
     * @param MyProject\xBundle\Email $email
     */
    public function addEmails(\MyProject\xBundle\Entity\Email $email)
    {
        $this->emails[] = $email;
    }

    /**
     * Get emails
     *
     * @return Doctrine\Common\Collections\Collection
     */
    public function getEmails()
    {
        return $this->emails;
    }

    /**
     * Set emails
     *
     * @param  $emails
     * @return Email
     */
    public function setEmails($emails)
    {
        $this->$emails = $emails;

        foreach ($emails as $email) {
            $email->setUser($this);
        }
    }

    /**
     *
     * @param string $user
     */
    public function setUser($user)
    {
        $this->user = $user;
    }
}

电子邮件.php

<?php

class Email
{
   /**
    * @var SystemUser
    *
    * @ORM\ManyToOne(targetEntity="User", cascade={"persist"})
    * @ORM\JoinColumns({
    *   @ORM\JoinColumn(name="system_user_id", referencedColumnName="id")
    * })
    *
    */
   private $systemUser;

   public function __construct()
   {
       $this->systemUser = new ArrayCollection();
   }

   /**
    *
    * @param MyProject\xBundle\Entity\User $systemUser
    */
   public function setSystemUser(\MyProject\xBundle\Entity\User $systemUsers = null)
   {
       $this->systemUser = $systemUser;

       return $this;
   }

   /**
    * Get systemUser
    *
    * @return MyProject\xBundle\Entity\User
    */
   public function getSystemUser()
   {
       return $this->systemUser;
   }

}

【问题讨论】:

    标签: forms symfony doctrine-orm sonata-admin


    【解决方案1】:

    您的方法需要从 UserEmail 实体的“前向”关系,否则管理员不知道要更改和坚持什么。更改User.php 中的代码,以便email 变量实际上知道它的关系。这意味着您应该添加类似

    的内容
    /**
     * @var array emails
     * @ORM\OneToMany(targetEntity="Email", mappedBy="systemUser", cascade={"all"})
     */
    protected $emails;
    

    【讨论】:

    • 感谢您的回复。我已经在 Symfony 论坛中找到了类似的案例。 forum.symfony-project.org/viewtopic.php?f=23&t=35914 但后来我遇到了几个问题,一个是我的 EmailType 类根本没有被阅读,所以只显示一个字段而不是两个。第二个问题出现在我尝试保存表单时:Expected argument of type "array", "string" given 我发现地址字段被发送了两次:首先作为字符串,然后作为数组。
    • 无论如何,这一切似乎都是在浪费时间,因为 Symfony 2.0 没有正确处理反向关系。 Symfony 2.1 的新 Form 类中正确实施了该修复。 github.com/symfony/symfony/issues/3539 github.com/symfony/symfony/issues/1540 所以我应该升级框架才能完成工作(因为2.0系列将支持到本月)。
    • 还有一件事:mappedBy="systemUser" 在 Doctrine 注释中是错误的,mappedBy 指向一个类属性,而不是任何数据库表。使用systemUser 会导致错误。
    • @user1595642 我建议您尝试使用sonata_type_collection 而不是collection,但我从来没有让那个工作。什么错误?
    • 其实sonata_type_collection是我的首选。它只是行不通。根本没有消息错误或警告。电子邮件表单被完全忽略,collection 改为显示表单。现在我正在将 Symfony 2.0 更新到 2.1。我希望能解决这个问题。
    猜你喜欢
    • 2015-01-29
    • 2018-02-09
    • 2016-06-25
    • 2012-12-26
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 2018-05-29
    • 1970-01-01
    相关资源
    最近更新 更多