У меня есть схема базы данных спортивных турниров, подобная этой
здесь у doman
есть от one to many
отношений с tournament
, у меня есть domain
форма, которая собирает данные о домене и хранит его в базе данных, у меня есть таблица турниров и доменов, подобная этой
tournament table
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| domain_id | int(11) | YES | MUL | NULL | |
| description | longtext | NO | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
Domain Table
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| subdomain | varchar(255) | NO | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
У меня есть tournamentType
, который собирает подробную информацию о турнире, но когда занесена там будет, очевидно, null
значение для domain_id
. как установить значение домена для всех tournaments
которые будут созданы, чтобы сказать domain_id = 1
.
я мог бы сделать это в контроллере с помощью сеттеров, но что бы грязное, есть ли способ, чтобы установить one
стороны от many
сторон в фреймворке встроенных форм,
edit: прямо сейчас я делаю это, внутри контроллера
$tournament->setDomain($em->getRepository("CricketBundle\Model\Entity\Domain")->findOneById(1));
$em->persist($tournament);
$em->flush();
и внутри организатора турнира
public function setDomain(\CricketBundle\Model\Entity\Domain $domain = null)
{
$domain->addTournament($this);
$this->domain = $domain;
return $this;
}
все отлично работает, я просто не хочу использовать сеттер внутри контроллера, я хочу переместить его в другое место
Вы всегда можете просто установить идентификатор домена по умолчанию в своей таблице турниров в базе данных и позволить базе данных обрабатывать его для вас.
Другой вариант - использовать прослушиватель prePersist
Doctrine на вашем объекте турнира в событии prePersist
, который возникает только до того, как этот объект впервые будет вставлен в базу данных, а не обновления. У Symfony есть документация о том, как это сделать. Более ранние версии Doctrine не поддерживали слушателей на одном объекте и требовали, чтобы вы прослушивали события для всего менеджера объектов, а затем проверяли, не является ли это подходящим объектом, но я собираюсь предположить, что вы находитесь на последние версии.
Итак, сначала вы бы определили слушателя на вашей стороне турнира как службу в любом загружаемом файле конфигурации:
services:
listener.tournament_entity:
class: CricketBundle\EventListener\TournamentListener
tags:
- { name: doctrine.orm.entity_listener }
Затем вы создадите свой TournamentListener:
<?php
namespace CricketBundle\EventListener;
use Doctrine\ORM\Event\LifecycleEventArgs;
use CricketBundle\Model\Entity\Tournament;
class TournamentListener
{
public function prePersist(Tournament $tournament, LifecycleEventArgs $eventArgs)
{
$em = $eventArgs->getEntityManager();
$domain = $em->getRepository('CricketBundle\Model\Entity\Domain')->find(1);
$tournament->setDomain($domain);
}
}
В вашем формате tournamentType
введите код, вам нужно добавить/или заменить следующий код:
$builder->add('domain', 'entity', array(
'class' => "YourBundle:DomainClass",
'empty_data' => '1')
);
Этот код инициализирует ваше поле в первом домене.
Если вы хотите, чтобы ваше поле было скрыто в форме, вы должны сменить тип своего поля на hidden
.