代码之家  ›  专栏  ›  技术社区  ›  Az.Youness

symfony-更新唯一的onetomany关系属性

  •  0
  • Az.Youness  · 技术社区  · 6 年前

    一家公司可以有多封电子邮件,所有电子邮件都必须是唯一的。
    这是我的公司和公司邮件

    公司邮件实体:

    /**
     * @ORM\Entity(repositoryClass="App\Repository\CompanyEmailRepository")
     * @UniqueEntity("name")
     */
    class CompanyEmail
    {
        /**
         * @ORM\Id()
         * @ORM\GeneratedValue()
         * @ORM\Column(type="integer")
         */
        private $id;
    
        /**
         * @ORM\Column(type="string", length=128, unique=true)
         * @Assert\Email()
         */
        private $name;
    
        /**
         * @ORM\ManyToOne(targetEntity="App\Entity\Company", inversedBy="emails")
         * @ORM\JoinColumn(nullable=false)
         */
        private $company;
    
        // ...
    }
    

    公司实体:

    /**
     * @ORM\Entity(repositoryClass="App\Repository\CompanyRepository")
     */
    class Company
    {
        // ...
    
        /**
         * @ORM\OneToMany(targetEntity="App\Entity\CompanyEmail", mappedBy="company", orphanRemoval=true, cascade={"persist"})
         * @Assert\Valid
         */
        private $emails;
    
        // ...
    }
    

    我用的是 电子邮件输入 用这个的 数据转换器

    class EmailArrayToStringTransformer implements DataTransformerInterface
    {
        public function transform($emails): string
        {
            return implode(', ', $emails);
        }
    
    
        public function reverseTransform($string): array
        {
            if ($string === '' || $string === null) {
                return [];
            }
    
            $inputEmails = array_filter(array_unique(array_map('trim', explode(',', $string))));
    
            $cEmails = [];
            foreach($inputEmails as $email){
                $cEmail = new CompanyEmail();
                $cEmail->setName($email);
                $cEmails[] = $cEmail;
            }
    
            return $cEmails;
        }
    }
    

    在控制器中使用这个编辑方法

    /**
         * @Route("/edit/{id}", name="admin_company_edit", requirements={"id": "\d+"}, methods={"GET", "POST"})
         */
        public function edit(Request $request, $id): Response
        {
            $entityManager = $this->getDoctrine()->getManager();
            $company = $entityManager->getRepository(Company::class)->find($id);
    
            $form = $this->createForm(CompanyType::class, $company);
    
            $form->handleRequest($request);
    
            if ($form->isSubmitted() && $form->isValid()) {
                $entityManager->flush();
            }
        }
    

    这个代码有两个问题

    1 -在编辑表单中,当我试图保存已经保存的电子邮件SyfFONY生成一个验证错误时,该错误通知该电子邮件已经退出。

    2-当我从代码中删除验证限制时,symfony抛出了数据库错误“*完整性约束冲突:1062重复项…*“。”

    我该怎么做才能让我的代码按预期工作!

    1 回复  |  直到 6 年前
        1
  •  1
  •   DonCallisto    6 年前

    问题就在这里

    public function reverseTransform($string): array
    {
      [...]
    
      foreach($inputEmails as $email){
        $cEmail = new CompanyEmail();
        [...]
      }
    
      [...]
    }
    

    你需要找回 email 而不是创造新的。 所以基本上,注射 CompanyEmailRepository 试着找出电子邮件是否已经存在( findOneBy(['name']) 如果它不存在,则创建一个新的,但是如果存在,使用您所检索到的。

    只有几个音符

    • 请注意电子邮件所有者(因此检索应该按每个用户进行,我想没有人可以共享相同的邮件,除非您可以指定一些别名或共享地址)
    • 也许你不需要像 CompanyEmail 因为你可以用 json 您可以以逗号分隔的方式存储它们(除非您需要一些额外的参数,或者除非您需要在电子邮件上执行一些索引/查询操作)。