Symfony2 - 持久化时管理与未使用实体的实体关系
Symfony2 - Managing Entity Relations To Unused Entities When Persisting
我有两个实体(Customer 和 PhoneNumber),它们通过 ManyToMany 连接相互关联。
当尝试以一种形式显示两个实体时,我使用了以下语句:
$customer = new Customer();
$customer->addPhoneNumber(new PhoneNumber());
$form = $this->createForm(new CustomerType(), $customer, array(
'action' => $this->generateUrl('customer_add'),
));
验证表单后,我需要检查表单中的电话号码部分是否已被使用,因为输入 phone 号码不是必需的。我需要这样做的原因是:当试图保留一个连接了 PhoneNumber-Entity 且没有设置任何值(= NULL 值)的客户时,我从数据库中得到一个 NOT NULL-Error。
所以我要做的是:验证表单后,如果没有输入 phone 号码,我会删除与客户的 PhoneNumber-Entity-Relation。
$phoneNumber = $customer->getPhoneNumbers()->first();
if(empty($phoneNumber->getPrefix()) && empty($phoneNumber->getNumber())) {
$customer->removePhoneNumber($phoneNumber);
}
这会导致以下问题:
- 我不再与 phone 数字实体有关系。现在我每次使用它时都必须对客户实体的关系进行各种检查。
- 另外,我不喜欢在验证成功后编辑客户实体这一事实。
- 如果一个实体与其他实体有很多关系,我在这里做的这个添加和删除过程可能会变得非常丑陋和混乱。
有没有更好的方法来完成我在这里尝试做的事情?
Customer.php:
/**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\PhoneNumber", mappedBy="customers", cascade={"persist"})
* @Assert\Valid()
**/
protected $phoneNumbers;
PhoneNumber.php:
/**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Customer", inversedBy="phoneNumbers", cascade={"persist"})
* @ORM\JoinTable(name="cp_relation")
**/
protected $customers;
CustomerType.php:
# ...
->add('phoneNumbers', 'collection', array(
'type' => new PhoneNumberType(),
'options' => array(
'required' => false,
)
))
正如聊天室讨论的那样,最好的解决方案是使用 collection type
并设置 allow_add=true
并使用 jQuery
& prototype
字段,让用户添加字段。
但在你的情况下(因为你不想使用 jquery
并依赖 js
),你可以将静态字段渲染为(不要忘记设置 allow_add=true
):
<input type="email" id="form_emails_0" name="form[emails][0]" value="" /><br>
<input type="email" id="form_emails_1" name="form[emails][1]" value="" />
我有两个实体(Customer 和 PhoneNumber),它们通过 ManyToMany 连接相互关联。
当尝试以一种形式显示两个实体时,我使用了以下语句:
$customer = new Customer();
$customer->addPhoneNumber(new PhoneNumber());
$form = $this->createForm(new CustomerType(), $customer, array(
'action' => $this->generateUrl('customer_add'),
));
验证表单后,我需要检查表单中的电话号码部分是否已被使用,因为输入 phone 号码不是必需的。我需要这样做的原因是:当试图保留一个连接了 PhoneNumber-Entity 且没有设置任何值(= NULL 值)的客户时,我从数据库中得到一个 NOT NULL-Error。
所以我要做的是:验证表单后,如果没有输入 phone 号码,我会删除与客户的 PhoneNumber-Entity-Relation。
$phoneNumber = $customer->getPhoneNumbers()->first();
if(empty($phoneNumber->getPrefix()) && empty($phoneNumber->getNumber())) {
$customer->removePhoneNumber($phoneNumber);
}
这会导致以下问题:
- 我不再与 phone 数字实体有关系。现在我每次使用它时都必须对客户实体的关系进行各种检查。
- 另外,我不喜欢在验证成功后编辑客户实体这一事实。
- 如果一个实体与其他实体有很多关系,我在这里做的这个添加和删除过程可能会变得非常丑陋和混乱。
有没有更好的方法来完成我在这里尝试做的事情?
Customer.php:
/**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\PhoneNumber", mappedBy="customers", cascade={"persist"})
* @Assert\Valid()
**/
protected $phoneNumbers;
PhoneNumber.php:
/**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Customer", inversedBy="phoneNumbers", cascade={"persist"})
* @ORM\JoinTable(name="cp_relation")
**/
protected $customers;
CustomerType.php:
# ...
->add('phoneNumbers', 'collection', array(
'type' => new PhoneNumberType(),
'options' => array(
'required' => false,
)
))
正如聊天室讨论的那样,最好的解决方案是使用 collection type
并设置 allow_add=true
并使用 jQuery
& prototype
字段,让用户添加字段。
但在你的情况下(因为你不想使用 jquery
并依赖 js
),你可以将静态字段渲染为(不要忘记设置 allow_add=true
):
<input type="email" id="form_emails_0" name="form[emails][0]" value="" /><br>
<input type="email" id="form_emails_1" name="form[emails][1]" value="" />