我有一个表单客户注册类型,带有嵌入地址表单(billingAddress和其他可选的ShippingAddress)。 如果用户没有检查"不同的送货地址"复选框,我的数据库地址表中应该只有一个地址。即便如此,我在地址表中得到两个不同的地址(具有相同的信息)。 但是,我查看" addAddress"如果在添加新地址之前地址已经存在。实际上在我的Customer FormType中,我以shippingAdress形式复制billingAddress表单数据,但在hasAdress方法中,$ this-> addresses-> contains($ address)返回false。我不明白为什么......
由于
这里是代码:
客户类
<?php
namespace DRMS\CustomerBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use DRMS\AddressingBundle\Entity\Address;
/**
* DRMS\CustomerBundle\Entity\Customer
*
* @ORM\Entity(repositoryClass="DRMS\CustomerBundle\Repository\CustomerRepository")
* @ORM\Table(name="customer", uniqueConstraints={@ORM\UniqueConstraint(name="customer_id_UNIQUE", columns={"customer_id"})})
*/
class Customer
{
/**
* @ORM\Id
* @ORM\Column(type="integer", name="customer_id")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $customerId;
// Others attributes
// ...
/**
* @ORM\OneToOne(targetEntity="DRMS\AddressingBundle\Entity\Address")
* @ORM\JoinColumn(name="billing_address_id", referencedColumnName="address_id")
*/
protected $billingAddress;
/**
* @ORM\OneToOne(targetEntity="DRMS\AddressingBundle\Entity\Address")
* @ORM\JoinColumn(name="shipping_address_id", referencedColumnName="address_id")
*/
protected $shippingAddress;
/**
* @ORM\OneToMany(targetEntity="DRMS\AddressingBundle\Entity\Address", mappedBy="customer", cascade={"remove", "persist"})
** ORM\JoinColumn(name="customer_id", referencedColumnName="customer_id", onDelete="CASCADE")
*/
protected $addresses;
public function __construct()
{
$this->addresses = new ArrayCollection();
}
/**
* Set the value of customerId.
*
* @param integer $customerId
* @return \DRMS\CustomerBundle\Entity\Customer
*/
public function setCustomerId($customerId)
{
$this->customerId = $customerId;
return $this;
}
/**
* Get the value of customerId.
*
* @return integer
*/
public function getCustomerId()
{
return $this->customerId;
}
// Others Getters/Setters
// ...
/**
* Set billingAddress
*
* @param \DRMS\AddressingBundle\Entity\Address $billingAddress
* @return Customer
*/
public function setBillingAddress(Address $billingAddress = null)
{
$this->billingAddress = $billingAddress;
if (null !== $billingAddress && !$this->hasAddress($billingAddress)) {
$this->addAddress($billingAddress);
}
return $this;
}
/**
* Get billingAddress
*
* @return \DRMS\AddressingBundle\Entity\Address
*/
public function getBillingAddress()
{
return $this->billingAddress;
}
/**
* Set shippingAddress
*
* @param \DRMS\AddressingBundle\Entity\Address $shippingAddress
* @return Customer
*/
public function setShippingAddress(Address $shippingAddress = null)
{
$this->shippingAddress = $shippingAddress;
if (null !== $shippingAddress && !$this->hasAddress($shippingAddress)) {
$this->addAddress($shippingAddress);
}
return $this;
}
/**
* Get shippingAddress
*
* @return \DRMS\AddressingBundle\Entity\Address
*/
public function getShippingAddress()
{
return $this->shippingAddress;
}
/**
* Add Address entity to collection (one to many).
*
* @param \DRMS\AddressingBundle\Entity\Address $address
* @return \DRMS\CustomerBundle\Entity\Customer
*/
public function addAddress(Address $address)
{
if (!$this->hasAddress($address)) {
$this->addresses->add($address);
$address->setCustomer($this);
}
return $this;
}
/**
* Remove Address
*
* @param \DRMS\AddressingBundle\Entity\Address $address
* @return \DRMS\CustomerBundle\Entity\Customer
*/
public function removeAddress(Address $address) {
$this->addresses->removeElement($address);
return $this;
}
/**
* Get Address entity collection (one to many).
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getAddresses()
{
return $this->addresses;
}
/**
* Has address
*
* @param \DRMS\AddressingBundle\Entity\Address $address
* @return bool
*/
public function hasAddress(Address $address)
{
return $this->addresses->contains($address);
}
}
地址类
<?php
namespace DRMS\AddressingBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* DRMS\AddressingBundle\Entity\Address
*
* @ORM\Entity(repositoryClass="DRMS\AddressingBundle\Repository\AddressRepository")
* @ORM\Table(name="address"), uniqueConstraints={@ORM\UniqueConstraint(name="customer_adress_UNIQUE", columns={"customer_id","address_id"})}
*/
class Address
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $address_id;
// Others attributes
// ...
/**
* @ORM\ManyToOne(targetEntity="DRMS\CustomerBundle\Entity\Customer", inversedBy="addresses", cascade={"remove"})
* @ORM\JoinColumn(name="customer_id", referencedColumnName="customer_id", onDelete="CASCADE")
*/
protected $customer;
/**
* Get the value of address_id.
*
* @return integer
*/
public function getAddressId()
{
return $this->address_id;
}
/**
* Set customer
*
* @param \DRMS\CustomerBundle\Entity\Customer $customer
* @return Address
*/
public function setCustomer(\DRMS\CustomerBundle\Entity\Customer $customer)
{
$this->customer = $customer;
return $this;
}
/**
* Get customer
*
* @return \DRMS\CustomerBundle\Entity\Customer
*/
public function getCustomer()
{
return $this->customer;
}
}
Customer FormType
<?php
# src\DRMS\CustomerBundle\Form\Type\CustomerType.php
namespace DRMS\CustomerBundle\Form\Type;
/**
* Description of CustomerType
*
*/
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
class CustomerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$data = $event->getData();
if (!array_key_exists('differentShippingAddress', $data) || false === $data['differentShippingAddress']) {
$data['shippingAddress'] = $data['billingAddress'];
$event->setData($data);
}
});
$builder->add('customerName', null)
->add('customerFirstname', null)
->add('phone')
->add('mobilePhone')
->add('billingAddress', 'drms_address', array(
'label' => 'drms.form.customer.billing_address',
))
->add('differentShippingAddress', 'checkbox', array(
'mapped' => false,
'label' => 'drms.form.customer.different_shipping_address',
'required' => false,
))
->add('shippingAddress', 'drms_address', array(
'label' => 'drms.form.customer.shipping_address',
))
;
}
/**
* @param OptionsResolverInterface $resolver
*
* If checkbox vatNumberOwner is checked, apply "vat_number_required" validation group for activate Vat Number test
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'DRMS\CustomerBundle\Entity\Customer',
'validation_groups' => function(FormInterface $form) {
$validation_groups = array('Registration');
if($form->get('differentShippingAddress')->getData() == true) {
$validation_groups[] = 'ShippingAddressRequired';
}
return $validation_groups;
},
));
}
public function getName()
{
return 'drms_customer';
}
}
答案 0 :(得分:1)
contains()
实现如此https://github.com/doctrine/collections/blob/master/lib/Doctrine/Common/Collections/ArrayCollection.php#L189这意味着您正在对对象标识进行严格比较。由于地址对象是由表单创建的,而不是由身份映射中的Doctrine管理,因此它不会与Doctrine创建的对象进行比较。由于不支持自定义集合,我建议您将in_array
逻辑更改为不严格,并将其直接放在您的实体中。