如何在 symfony2 中从多个方面创建嵌入表单

How to create embed forms from the many side in symfony2

我有一个像这样的体育比赛数据库模式

此处 domantournamentone 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);
    }
}