Доктрина: значение по умолчанию в поле joinColumn

Новое в symfony2 и Doctrine.

Как я могу установить значение по умолчанию для поля foo_id (который является ссылкой на Foo таблица), чтобы указать на ID 1 таблицы Foo (которая существует во всех случаях)?

Me\NavigationBundle\Entity\PublicText:
type: entity
table: public_text
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
title:
type: string
length: '255'
nullable: false
content:
type: string
length: '2000'
nullable: false
manyToOne:
foo:
#How to set a default value???
targetEntity: \Me\NavigationBundle\Entity\Foo
joinColumn:
name: foo_id
referencedColumnName: id
nullable: false
lifecycleCallbacks: {  }

Я много чего перепробовал безуспешно

  • Установите значение по умолчанию для ID 1 в конструкторе Foo
  • Выполнить запрос на получение объекта Foo с идентификатором 1 в сущности Me (может работать, но плохая практика)

2

Решение

Я видел много способов достичь этого в доктрине 2.

В общем, самый быстрый способ и то, что делает большинство пользователей, это требует ассоциации в конструкторе.

public function __construct(Foo $foo)
{
$this->foo = $foo;
}

Тогда вы можете использовать getReference чтобы получить его в вашем контроллере без необходимости запрашивать базу данных. Увидеть http://doctrine-orm.readthedocs.org/en/latest/reference/advanced-configuration.html#reference-proxies

$foo = $em->getReference('app:Foo', 1);
$text = new \Path\To\Entity\PublicText($foo);
$em->persist($text);
$em->flush();

Мой предпочтительный способ установить значение по умолчанию с большинством ManyToOne отношения, чтобы использовать LifeCycleEvents http://doctrine-orm.readthedocs.org/en/latest/reference/events.html

Хотя у этого есть некоторые предостережения, о которых нужно знать. Так что обязательно RTM перед внедрением в производственную среду. В этом случае все должно работать нормально, но я не знаю всей вашей структуры отображения.

 use Doctrine\ORM\Event\LifecycleEventArgs;

/**
* @Entity
* @HasLifeCycleEvents
*/
class PublicText
{
// ...

/**
* @PrePersist
* @param \Doctrine\ORM\Event\LifecycleEventArgs $event
*/
public function onPrePersist(LifecycleEventArgs $event)
{
if (false === empty($this->foo)) {
return;
}
$this->foo = $event->getEntityManager()->getReference('app:Foo', 1);
}
}

Тогда в вашем контроллере.

$text = new \Path\To\Entity\PublicText;
$em->persist($text); //retrieve and set foo if not set in the Entity Event.
$em->flush();

Другой вариант в вашей сущности — просто установить значение свойства с помощью репозитория.

Определить класс репозитория в сущности

/**
* @Entity(repositoryClass="PublicTextRepo")
*/
class PublicText
{
// ...
}

вместилище

use Doctrine\ORM\EntityRepository;

class PublicTextRepo extends EntityRepository
{
public function create()
{
$text = new \Path\To\Entity\PublicText;
$foo = $this->_em->getReference('app:Foo', 1);
$text->setFoo($foo );
return $text;
}
}

Затем в вашем контроллере вы можете сделать

$text = $em->getRepository('app:PublicText')->create();
$em->persist($text);
$em->flush();

Хотя не всегда жизнеспособно в зависимости от варианта использования. Один из способов определения значения сущности по умолчанию — создание DiscriminatorMap с наследованием одной таблицы. http://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html#single-table-inheritance.

Таким образом, при создании объекта значение по умолчанию автоматически устанавливается в базе данных, и объект блокируется как этот тип. Проблема в том, что полученное значение не объект как в других методах выше.

Чтобы получить дискриминатор объекта static значение, вы можете использовать константы внутри объектов, которые вы определяете.

/**
* @Entity
* @InheritanceType("SINGLE_TABLE")
* @Table(name="user")
* @DiscriminatorColumn(name="type", type="string")
* @DiscriminatorMap({Person::TYPE="Person", Employee::TYPE="Employee"})
*/
class Person
{
const TYPE = 'person';

/**
* @return Person|Employee
*/
public function getType()
{
return $this::TYPE;
}
// ...
}

/**
* @Entity
*/
class Employee extends Person
{
const TYPE = 'employee';
// ...
}

Тогда все, что вам нужно сделать в вашем контроллере, это.

$employee = new \Path\To\Entity\Employee;
$em->persist($employee); //inserts with `user.type` as `employee`
$em->flush();

echo $employee->getType(); //employee
1

Другие решения

Уважать columnDefinition в Справочник по колонкам доктрин

Плюсы: Вы можете настроить собственное определение столбца

Минусы: doctrine orm:schema-tool используется доктриной (если вы используете его), запутывается и всегда столбцы отчетов, которые имеют пользовательские columnDefinition как изменилось. Как это всегда будет говорить вам, чтобы запустить команду изменения для определения столбца, как описано Вот:

SchemaTool больше не будет правильно определять изменения в столбце, если вы используете «columnDefinition».

пример

/**
* @ManyToOne(targetEntity="YourType")
* @JoinColumn(
*     name="your_type_id",
*     referencedColumnName="id",
*     nullable=false,
*     columnDefinition="INT NOT NULL DEFAULT 1"* )
*/
private $yourType;
2

С аннотацией вы можете использовать: options = {«default» = YourValue} в столбце @ORM \, поэтому в yaml я думаю, что вы можете добавить

options:
default: yourValue

Я не уверен, я представляю вам идею …

-1
По вопросам рекламы [email protected]