Symfony - 更新唯一的一对多关系属性



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

公司电子邮件实体:

/**
* @ORMEntity(repositoryClass="AppRepositoryCompanyEmailRepository")
* @UniqueEntity("name")
*/
class CompanyEmail
{
/**
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMColumn(type="string", length=128, unique=true)
* @AssertEmail()
*/
private $name;
/**
* @ORMManyToOne(targetEntity="AppEntityCompany", inversedBy="emails")
* @ORMJoinColumn(nullable=false)
*/
private $company;
// ...
}

公司实体:

/**
* @ORMEntity(repositoryClass="AppRepositoryCompanyRepository")
*/
class Company
{
// ...
/**
* @ORMOneToMany(targetEntity="AppEntityCompanyEmail", mappedBy="company", orphanRemoval=true, cascade={"persist"})
* @AssertValid
*/
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 - 当我尝试保留已经保存的电子邮件时,在编辑表单中,Symfony会生成一个验证错误,告知此电子邮件已经退出。

2 - 当我从代码中删除验证限制时,Symfony抛出了数据库错误"*完整性约束违规:1062重复条目... *">

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

问题就在这里

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

您需要检索email,而不是创建新。 所以基本上,注入一个CompanyEmailRepository,尝试查找电子邮件是否已经存在(findOneBy(['name'])),如果不存在,创建一个新的,但如果存在,请使用您检索到的内容。

只需几点笔记

  • 注意电子邮件所有者(所以检索应该是每个用户做的,我猜因为没有人可以共享同一封邮件,除非你可以指定一些别名或共享地址)
  • 也许您不需要像CompanyEmail这样的额外实体,因为您可以使用json字段,您可以在其中以逗号分隔的方式存储它们(除非您需要一些额外的参数,或者除非您需要对电子邮件执行一些索引/查询操作)

相关内容

  • 没有找到相关文章

最新更新