簡體   English   中英

Symfony-更新唯一的OneToMany關系屬性

[英]Symfony - Update a unique OneToMany relation property

一個公司可以有多個電子郵件,並且所有電子郵件都必須是唯一的。
這是我公司和公司電子郵件的實體

CompanyEmail實體:

/**
 * @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;

    // ...
}

我正在使用使用此DataTransformer的自定義EmailsInputType

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;
    }
}

並在Controller中使用此編輯方法

/**
     * @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-在編輯表單中,當我嘗試保留已保存的電子郵件時,Symfony會生成一個驗證錯誤,告訴您該電子郵件已退出。

2-當我從代碼中刪除驗證限制時,Symfony拋出數據庫錯誤“ *完整性約束沖突:1062復制條目... *”

我應該怎么做才能使我的代碼按預期工作!

問題就在這里

public function reverseTransform($string): array
{
  [...]

  foreach($inputEmails as $email){
    $cEmail = new CompanyEmail();
    [...]
  }

  [...]
}

您需要檢索email而不是創建新email 因此,基本上,注入一個CompanyEmailRepository ,嘗試查找是否已經存在電子郵件( findOneBy(['name']) ),如果不存在,則創建一個新電子郵件,但如果存在,則使用您檢索的內容。

只是一些筆記

  • 注意電子郵件所有者(因此檢索應該針對每個用戶,因為我猜沒有人可以共享同一封郵件,除非您可以指定一些別名或共享地址)
  • 也許您不需要像CompanyEmail這樣的額外實體,因為您可以使用json字段,以逗號分隔的方式存儲它們(除非您需要一些額外的參數,或者除非您需要對電子郵件執行一些索引/查詢操作)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM