Symfony2 — Управление отношениями сущностей к неиспользуемым сущностям при сохранении

У меня есть две сущности (Customer и PhoneNumber), которые находятся в реальной связи друг с другом через соединение ManyToMany.

При попытке отобразить обе сущности в одной форме я использую следующие операторы:

$customer = new Customer();
$customer->addPhoneNumber(new PhoneNumber());
$form = $this->createForm(new CustomerType(), $customer, array(
    'action' => $this->generateUrl('customer_add'),
));

После проверки формы мне нужно проверить, использовался ли раздел PhoneNumber в форме или нет, поскольку ввод номера телефона не является обязательным. Причина, по которой мне нужно это сделать, заключается в следующем: при попытке сохранить клиента, к которому подключен объект PhoneNumber-Entity, для которого не установлены значения (= значения NULL), я получаю NOT NULL-Error из базы данных.

Итак, что я делаю: после проверки формы я удаляю PhoneNumber-Entity-Relation для клиента, если номер телефона не был введен.

$phoneNumber = $customer->getPhoneNumbers()->first();
if(empty($phoneNumber->getPrefix()) && empty($phoneNumber->getNumber())) {
    $customer->removePhoneNumber($phoneNumber);
}

Это вызывает следующие проблемы:

  • Я больше не имею отношения к объекту телефонного номера. Теперь мне приходится выполнять различные проверки отношений клиент-сущность каждый раз, когда я его использую.
  • Также мне не нравится тот факт, что я редактирую объект клиента после его успешной проверки.
  • В случае, если объект имеет много отношений с другими объектами, процесс добавления и удаления, который я здесь делаю, может стать очень уродливым и запутанным.

Есть ли лучший способ сделать то, что я пытаюсь сделать здесь?


Клиент.php:

/**
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\PhoneNumber", mappedBy="customers", cascade={"persist"})
 * @Assert\Valid()
 **/
protected $phoneNumbers;

Номер телефона.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,
          )
     ))

person chrisp    schedule 17.04.2015    source источник
comment
скопируйте сюда свою форму и сопоставление сущностей или прочитайте этот документ: symfony.com /doc/current/reference/forms/types/collection.html   -  person ghanbari    schedule 18.04.2015
comment
Готово. Возможно, это как-то связано с delete_empty и allow_delete, но я не уверен, что это полностью решит проблемы, о которых я говорил.   -  person chrisp    schedule 18.04.2015
comment
Хорошо, я правильно понял: включение delete_empty удалит все пустые формы, если в эти поля не были вставлены данные. Чтобы иметь возможность редактировать клиентов позже и, возможно, удалить номер телефона, мне придется включить allow_delete. С этим набором, а также с обеспечением постоянного отношения к базе данных при редактировании клиентов, все должно работать правильно?   -  person chrisp    schedule 18.04.2015
comment
при использовании allow_add вам не нужно указывать номер телефона клиента. $customer = new Customer(); $customer->addPhoneNumber(new PhoneNumber());   -  person ghanbari    schedule 18.04.2015
comment
Но разве мне не нужна эта часть, чтобы показать пользователю поля в шаблоне?   -  person chrisp    schedule 18.04.2015
comment
используйте прототип и jquery для отображения пользовательских полей   -  person ghanbari    schedule 18.04.2015
comment
Давайте продолжим обсуждение в чате.   -  person chrisp    schedule 18.04.2015


Ответы (1)


Как обсуждалось в чате, лучшим решением является использование 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="" />
person ghanbari    schedule 18.04.2015