【问题标题】:Symfony2 form update one-to-one relationSymfony2 表单更新一对一关系
【发布时间】:2016-06-23 18:05:06
【问题描述】:

我需要有关 Symfony2 表单一对一关系更新的帮助。我必须实体:用户和用户信息

用户实体:

class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Group")
     * @ORM\JoinTable(name="fos_user_user_group",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
     * )
     */
    protected $groups;

    /**
     * @ORM\OneToOne(targetEntity="UserInfo", mappedBy="user", cascade={"all"})
     */
    private $info;

    /**
     * @ORM\OneToMany(targetEntity="Log", mappedBy="user")
     */
    private $logs;

    public function __construct()
    {
        parent::__construct();
        $this->logs = new ArrayCollection();
    }

    /**
     * Set info
     *
     * @param \AppBundle\Entity\UserInfo $info
     * @return User
     */
    public function setInfo(\AppBundle\Entity\UserInfo $info = null)
    {
        $this->info = $info;
        $info->setUser($this);

        return $this;
    }

    /**
     * Get info
     *
     * @return \AppBundle\Entity\UserInfo 
     */
    public function getInfo()
    {
        return $this->info;
    }

    /**
     * Add logs
     *
     * @param \AppBundle\Entity\Log $logs
     * @return User
     */
    public function addLog(\AppBundle\Entity\Log $logs)
    {
        $this->logs[] = $logs;

        return $this;
    }

    /**
     * Remove logs
     *
     * @param \AppBundle\Entity\Log $logs
     */
    public function removeLog(\AppBundle\Entity\Log $logs)
    {
        $this->logs->removeElement($logs);
    }

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

用户信息实体:

class UserInfo
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="position", type="string", length=255)
     */
    private $position;

    /**
     * @var string
     *
     * @ORM\Column(name="info", type="text")
     */
    private $info;

    /**
     * @var string
     *
     * @ORM\Column(name="fullname", type="string", length=255)
     */
    private $fullname;

    /**
     * @ORM\OneToOne(targetEntity="User", inversedBy="info")
     */
    private $user;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set position
     *
     * @param string $position
     * @return UserInfo
     */
    public function setPosition($position)
    {
        $this->position = $position;

        return $this;
    }

    /**
     * Get position
     *
     * @return string 
     */
    public function getPosition()
    {
        return $this->position;
    }

    /**
     * Set info
     *
     * @param string $info
     * @return UserInfo
     */
    public function setInfo($info)
    {
        $this->info = $info;

        return $this;
    }

    /**
     * Get info
     *
     * @return string 
     */
    public function getInfo()
    {
        return $this->info;
    }

    /**
     * Set fullname
     *
     * @param string $fullname
     * @return UserInfo
     */
    public function setFullname($fullname)
    {
        $this->fullname = $fullname;

        return $this;
    }

    /**
     * Get fullname
     *
     * @return string 
     */
    public function getFullname()
    {
        return $this->fullname;
    }

    /**
     * Set user
     *
     * @param \AppBundle\Entity\User $user
     * @return UserInfo
     */
    public function setUser(\AppBundle\Entity\User $user = null)
    {
        $this->user = $user;

        return $this;
    }

    /**
     * Get user
     *
     * @return \AppBundle\Entity\User 
     */
    public function getUser()
    {
        return $this->user;
    }
}

这些是它们的类型:

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('username')
            ->add('email')
            ->add('password')
            ->add('info', new UserInfoType(), [
                'by_reference' => false,
            ])
            ->add('Submit', 'submit')
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'AppBundle\Entity\User',
        ]);
    }

    public function getName()
    {
        return 'user';
    }
}

class UserInfoType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('position')
            ->add('info')
            ->add('fullname')
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'AppBundle\Entity\UserInfo',
            'allow_delete' => true,
        ]);
    }

    public function getName()
    {
        return 'userinfo';
    }
}

新记录插入没有任何问题,但是当我想使用此操作更新此记录时:

public function editAction(Request $request, $id)
{
    $em = $this->getDoctrine()->getManager();

    $userRepository = $em->getRepository('AppBundle:User');

    $user = $userRepository->findOneBy(['id' => $id]);

    $form = $this->createForm(new UserType(), $user);

    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $em->persist($user);
        $em->flush();

        return $this->redirectToRoute('user_list');
    }

    return $this->render('@App/User/form.html.twig', [
        'form' => $form->createView(),
    ]);
}

我收到此错误:

An exception occurred while executing 'INSERT INTO user_info (position, info, fullname, user_id) VALUES (?, ?, ?, ?)' with params ["321", "321", "321", 14]:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '14' for key 'UNIQ_B1087D9EA76ED395'

好的,我知道他想插入新记录,但我应该怎么做才能让他更新或删除现有记录并插入新记录。

【问题讨论】:

  • 如何将fetch="EAGER" 添加到User$info 属性?
  • @PawełMikołajczuk Nop,还是一样。

标签: php symfony formcollection


【解决方案1】:

尝试将User 设为拥有方,将UserInfo 设为相反方(参见docs)。

class User extends BaseUser
{
    /**
     * @ORM\OneToOne(targetEntity="UserInfo", inversedBy="user", cascade={"all"})
     */
    private $info;
}

class UserInfo
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

/**
  * @ORM\OneToOne(targetEntity="User", mappedBy="info")
  */
    private $user;
}

也与this SO question有关。

编辑:要在更新后删除旧的、未引用的UserInfo 记录,请在User 类的info 属性中设置orphanRemoval 选项。

class User extends BaseUser
{
    /**
     * @ORM\OneToOne(targetEntity="UserInfo", inversedBy="user", cascade={"all"}, orphanRemoval=true)
     */
    private $info;
}

【讨论】:

  • 现在它将信息插入UserInfo 表并更新User 表中的info_id 列。旧记录只是挂在表中。如何删除旧记录?
  • 试试 Pawel 的评论并将 fetch="EAGER" 添加到 User 类中的 info 属性中。
  • 你试过orphanRemoval 吗?
【解决方案2】:

你需要在你的User类中使用JoinColumn注解:

/**
 * @ORM\OneToOne(targetEntity="UserInfo", inversedBy="user", cascade={"all"})
 * @ORM\JoinColumn(name="info", referencedColumnName="id")
 */
private $info;

用户信息:

/**
* @ORM\OneToOne(targetEntity="User", mappedBy="info")
*/
private $user;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 2014-09-29
    • 1970-01-01
    • 2016-01-03
    相关资源
    最近更新 更多