Как создать встраиваемые формы со многих сторон в symfony2

1

У меня есть схема базы данных спортивных турниров, подобная этой

Изображение 174551

здесь у 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;
    }

все отлично работает, я просто не хочу использовать сеттер внутри контроллера, я хочу переместить его в другое место

  • 0
    Хотите создать одну форму с 2 сущностями?
  • 0
    @Trone Трон да, любая техника, которая позволяет мне элегантно достичь вышеуказанных отношений, будет приемлемой
Показать ещё 3 комментария
Теги:
symfony-2.8
symfony-forms

2 ответа

2
Лучший ответ

Вы всегда можете просто установить идентификатор домена по умолчанию в своей таблице турниров в базе данных и позволить базе данных обрабатывать его для вас.

Другой вариант - использовать прослушиватель 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);
    }
}
1

В вашем формате tournamentType введите код, вам нужно добавить/или заменить следующий код:

$builder->add('domain', 'entity', array(
  'class' => "YourBundle:DomainClass", 
  'empty_data' => '1')
);

Этот код инициализирует ваше поле в первом домене.

Если вы хотите, чтобы ваше поле было скрыто в форме, вы должны сменить тип своего поля на hidden.

  • 0
    Отличное предложение! альтернативно, случайно ли было бы хорошо, если бы я установил сущность в классе репозитория?
  • 0
    Это еще одна возможность, на мой взгляд, я предпочитаю использовать формы для максимально возможного открытия кода. Вы можете специализировать свою сущность с помощью форм, возможно, в будущей версии вы сможете выбрать несколько доменов ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню