如何在 symfony2 中从多个方面创建嵌入表单
How to create embed forms from the many side in symfony2
我有一个像这样的体育比赛数据库模式
此处 doman
与 tournament
有 one to many
关系,我有一个 domain
表单,用于收集域详细信息并将其存储在数据库中,我有锦标赛和域名 table 像这样
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
收集比赛的详细信息,但是当提交时显然 domain_id
会有一个 null
值。我如何为将创建的所有 tournaments
设置域值,让我们说 domain_id = 1
。
我可以在控制器中使用 setters 来做到这一点,但这会很麻烦,有没有办法在 symfony 中从 many
一侧设置 one
一侧嵌入式表格,
编辑:现在我正在控制器内部执行此操作
$tournament->setDomain($em->getRepository("CricketBundle\Model\Entity\Domain")->findOneById(1));
$em->persist($tournament);
$em->flush();
和内部锦标赛实体的 setter
public function setDomain(\CricketBundle\Model\Entity\Domain $domain = null)
{
$domain->addTournament($this);
$this->domain = $domain;
return $this;
}
一切都很好,我只是不想使用控制器内部的 setter,我想将它移到其他地方
在您的表单tournamentType
表单代码中,您需要添加/或替换以下代码:
$builder->add('domain', 'entity', array(
'class' => "YourBundle:DomainClass",
'empty_data' => '1')
);
此代码将您的字段初始化为第一个域。
如果您希望您的字段在表单中隐藏,您必须将字段类型更改为 hidden
。
您总是可以在数据库中设置锦标赛 table 的默认域 ID,让数据库为您处理。
另一种选择是使用 Doctrine entity listener on your Tournament entity on the prePersist
event, which only occurs before that entity is inserted into the database for the first time, and not on updates. Symfony has some documentation 如何做到这一点。 Doctrine 的早期版本不支持单个实体上的监听器,并且要求您监听整个实体管理器的事件,然后检查它是否是您想要的正确实体,但我假设您在最新版本。
因此,首先您要将 Tournament 实体上的侦听器定义为正在加载的任何配置文件中的服务:
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);
}
}
我有一个像这样的体育比赛数据库模式
此处 doman
与 tournament
有 one to many
关系,我有一个 domain
表单,用于收集域详细信息并将其存储在数据库中,我有锦标赛和域名 table 像这样
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
收集比赛的详细信息,但是当提交时显然 domain_id
会有一个 null
值。我如何为将创建的所有 tournaments
设置域值,让我们说 domain_id = 1
。
我可以在控制器中使用 setters 来做到这一点,但这会很麻烦,有没有办法在 symfony 中从 many
一侧设置 one
一侧嵌入式表格,
编辑:现在我正在控制器内部执行此操作
$tournament->setDomain($em->getRepository("CricketBundle\Model\Entity\Domain")->findOneById(1));
$em->persist($tournament);
$em->flush();
和内部锦标赛实体的 setter
public function setDomain(\CricketBundle\Model\Entity\Domain $domain = null)
{
$domain->addTournament($this);
$this->domain = $domain;
return $this;
}
一切都很好,我只是不想使用控制器内部的 setter,我想将它移到其他地方
在您的表单tournamentType
表单代码中,您需要添加/或替换以下代码:
$builder->add('domain', 'entity', array(
'class' => "YourBundle:DomainClass",
'empty_data' => '1')
);
此代码将您的字段初始化为第一个域。
如果您希望您的字段在表单中隐藏,您必须将字段类型更改为 hidden
。
您总是可以在数据库中设置锦标赛 table 的默认域 ID,让数据库为您处理。
另一种选择是使用 Doctrine entity listener on your Tournament entity on the prePersist
event, which only occurs before that entity is inserted into the database for the first time, and not on updates. Symfony has some documentation 如何做到这一点。 Doctrine 的早期版本不支持单个实体上的监听器,并且要求您监听整个实体管理器的事件,然后检查它是否是您想要的正确实体,但我假设您在最新版本。
因此,首先您要将 Tournament 实体上的侦听器定义为正在加载的任何配置文件中的服务:
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);
}
}