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

Как установить значение по умолчанию в Doctrine 2?

Solutions Collecting From Web of "Значение по умолчанию в Доктрине"

Значения по умолчанию для базы данных не поддерживаются «переносимо». Единственный способ использовать значения по умолчанию для базы данных – это columnDefinition сопоставления columnDefinition котором вы указываете фрагмент SQL (причина DEFAULT включительно) для столбца, к columnDefinition поле.

Вы можете использовать:

 <?php /** * @Entity */ class myEntity { /** * @var string * * @Column(name="myColumn", type="string", length="50") */ private $myColumn = 'myDefaultValue'; ... } 

Предпочтительны значения по умолчанию на уровне PHP, так как они также правильно доступны для вновь созданных и сохраняемых объектов (Doctrine не вернется к базе данных после сохранения нового объекта, чтобы получить значения по умолчанию).

 @ORM\Column(name="foo", type="decimal", precision=7, scale=2, options={"default" : 0}) 

Обратите внимание, что это использует SQL DEFAULT , который не поддерживается для некоторых полей, таких как BLOB и TEXT .

Настройте конструктор в своей сущности и установите для него значение по умолчанию.

Использование:

 options={"default":"foo bar"} 

и не:

 options={"default"="foo bar"} 

Например:

 /** * @ORM\Column(name="foo", type="smallint", options={"default":0}) */ private $foo 

Обновить

Еще одна причина, по которой чтение документации для Symfony никогда не исчезнет из тенденции. Для моего конкретного случая есть простое решение и установить значение field type empty_data в значение по умолчанию.

Опять же, это решение предназначено только для сценария, когда пустой ввод в форме устанавливает для поля БД значение null.

Задний план

Ни один из предыдущих ответов не помог мне с моим конкретным сценарием, но я нашел решение.

У меня было поле формы, которое должно было вести себя следующим образом:

  1. Не требуется, может быть оставлено пустым. (Используется «required» => false)
  2. Если он оставлен пустым, он должен иметь значение по умолчанию. Для лучшего удобства пользователей я не установил значение по умолчанию в поле ввода, а скорее использовал атрибут html «placeholder», поскольку он менее навязчив.

Затем я попробовал все рекомендации, приведенные здесь. Позвольте мне перечислить их:

  • Установите значение по умолчанию для свойства entity:
 <?php /** * @Entity */ class myEntity { /** * @var string * * @Column(name="myColumn", type="string", length="50") */ private $myColumn = 'myDefaultValue'; ... } 
  • Используйте аннотацию параметров:
 @ORM\Column(name="foo", options={"default":"foo bar"}) 
  • Задайте значение по умолчанию для конструктора:
 /** * @Entity */ class myEntity { ... public function __construct() { $this->myColumn = 'myDefaultValue'; } ... } 

Ничего из этого не было, и все из-за того, как Symfony использует ваш класс Entity.

ВАЖНЫЙ

Поля формы Symfony переопределяют значения по умолчанию, заданные в классе Entity. Смысл, ваша схема для вашей БД может иметь значение по умолчанию, но если вы оставите необязательное поле пустым при отправке своей формы, form->handleRequest() внутри вашего метода form->handleRequest() form->isValid() переопределит эти значения по умолчанию на ваш класс Entity и установите их в значения полей ввода. Если значения поля ввода пустые, тогда для свойства Entity будет установлено значение null .

http://symfony.com/doc/current/book/forms.html#handling-form-submissions

Мое обходное решение

Задайте значение по умолчанию на вашем контроллере после form->handleRequest() внутри метода form->handleRequest() form->isValid() :

 ... if ($myEntity->getMyColumn() === null) { $myEntity->setMyColumn('myDefaultValue'); } ... 

Не красивое решение, но оно работает. Возможно, я мог бы сделать validation group но могут быть люди, которые рассматривают эту проблему как преобразование данных, а не проверку данных , я оставляю ее вам решать.


Переопределить сеттер (не работает)

Я также попытался переопределить Entity :

 ... /** * Set myColumn * * @param string $myColumn * * @return myEntity */ public function setMyColumn($myColumn) { $this->myColumn = ($myColumn === null || $myColumn === '') ? 'myDefaultValue' : $myColumn; return $this; } ... 

Это, несмотря на то, что выглядит более чистым, не работает . Причина заключается в том, что метод злой формы – form->handleRequest() не использует методы сеттера модели для обновления данных (для более подробной информации form->handleRequest() form->setData() ).

Обходной путь, который я использовал, был LifeCycleCallback . Все еще ждет, есть ли более «родной» метод, например @Column(type="string", default="hello default value") .

 /** * @Entity @Table(name="posts") @HasLifeCycleCallbacks */ class Post implements Node, \Zend_Acl_Resource_Interface { ... /** * @PrePersist */ function onPrePersist() { // set default date $this->dtPosted = date('Ymd H:m:s'); } 

Вы можете сделать это, используя xml:

 <field name="acmeOne" type="string" column="acmeOne" length="36"> <options> <option name="comment">Your SQL field comment goes here.</option> <option name="default">Default Value</option> </options> </field> 

Работает для меня и в базе данных mysql:

 Entity\Entity_name: type: entity table: table_name fields: field_name: type: integer nullable: true options: default: 1 

Вот как я решил это для себя. Ниже приведен пример Entity со значением по умолчанию для MySQL. Однако для этого также требуется настройка конструктора в вашей сущности и для установки значения по умолчанию.

 Entity\Example: type: entity table: example fields: id: type: integer id: true generator: strategy: AUTO label: type: string columnDefinition: varchar(255) NOT NULL DEFAULT 'default_value' COMMENT 'This is column comment' 

Ничто из этого не сработало для меня. Я нашел некоторую документацию на сайте доктрины, которая говорит, чтобы установить значение непосредственно для установки значения по умолчанию.

http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/faq.html

 private $default = 0; 

Это вставило значение, которое я хотел.

Добавление в @romanb блестящего ответа.

Это добавляет небольшие затраты на перенос, потому что вы, очевидно, не можете создать поле с нулевым ограничением и без значения по умолчанию.

 // this up() migration is autogenerated, please modify it to your needs $this->abortIf($this->connection->getDatabasePlatform()->getName() != "postgresql"); //lets add property without not null contraint $this->addSql("ALTER TABLE tablename ADD property BOOLEAN"); //get the default value for property $object = new Object(); $defaultValue = $menuItem->getProperty() ? "true":"false"; $this->addSql("UPDATE tablename SET property = {$defaultValue}"); //not you can add constraint $this->addSql("ALTER TABLE tablename ALTER property SET NOT NULL"); 

С помощью этого ответа я рекомендую вам подумать, почему вам нужно значение по умолчанию в базе данных в первую очередь? И обычно это позволяет создавать объекты с ненулевым ограничением.

Если вы используете определение yaml для своей сущности, для меня в базе данных postgresql работает следующее:

 Entity\Entity_name: type: entity table: table_name fields: field_name: type: boolean nullable: false options: default: false 

Я боролся с той же проблемой. Я хотел иметь значение по умолчанию из базы данных в сущности (автоматически). Угадайте, я сделал это 🙂

 <?php /** * Created by JetBrains PhpStorm. * User: Steffen * Date: 27-6-13 * Time: 15:36 * To change this template use File | Settings | File Templates. */ require_once 'bootstrap.php'; $em->getConfiguration()->setMetadataDriverImpl( new \Doctrine\ORM\Mapping\Driver\DatabaseDriver( $em->getConnection()->getSchemaManager() ) ); $driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($em->getConnection()->getSchemaManager()); $driver->setNamespace('Models\\'); $em->getConfiguration()->setMetadataDriverImpl($driver); $cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory(); $cmf->setEntityManager($em); $metadata = $cmf->getAllMetadata(); // Little hack to have default values for your entities... foreach ($metadata as $k => $t) { foreach ($t->getFieldNames() as $fieldName) { $correctFieldName = \Doctrine\Common\Util\Inflector::tableize($fieldName); $columns = $tan = $em->getConnection()->getSchemaManager()->listTableColumns($t->getTableName()); foreach ($columns as $column) { if ($column->getName() == $correctFieldName) { // We skip DateTime, because this needs to be a DateTime object. if ($column->getType() != 'DateTime') { $metadata[$k]->fieldMappings[$fieldName]['default'] = $column->getDefault(); } break; } } } } // GENERATE PHP ENTITIES! $entityGenerator = new \Doctrine\ORM\Tools\EntityGenerator(); $entityGenerator->setGenerateAnnotations(true); $entityGenerator->setGenerateStubMethods(true); $entityGenerator->setRegenerateEntityIfExists(true); $entityGenerator->setUpdateEntityIfExists(false); $entityGenerator->generate($metadata, __DIR__); echo "Entities created"; функции <?php /** * Created by JetBrains PhpStorm. * User: Steffen * Date: 27-6-13 * Time: 15:36 * To change this template use File | Settings | File Templates. */ require_once 'bootstrap.php'; $em->getConfiguration()->setMetadataDriverImpl( new \Doctrine\ORM\Mapping\Driver\DatabaseDriver( $em->getConnection()->getSchemaManager() ) ); $driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($em->getConnection()->getSchemaManager()); $driver->setNamespace('Models\\'); $em->getConfiguration()->setMetadataDriverImpl($driver); $cmf = new \Doctrine\ORM\Tools\DisconnectedClassMetadataFactory(); $cmf->setEntityManager($em); $metadata = $cmf->getAllMetadata(); // Little hack to have default values for your entities... foreach ($metadata as $k => $t) { foreach ($t->getFieldNames() as $fieldName) { $correctFieldName = \Doctrine\Common\Util\Inflector::tableize($fieldName); $columns = $tan = $em->getConnection()->getSchemaManager()->listTableColumns($t->getTableName()); foreach ($columns as $column) { if ($column->getName() == $correctFieldName) { // We skip DateTime, because this needs to be a DateTime object. if ($column->getType() != 'DateTime') { $metadata[$k]->fieldMappings[$fieldName]['default'] = $column->getDefault(); } break; } } } } // GENERATE PHP ENTITIES! $entityGenerator = new \Doctrine\ORM\Tools\EntityGenerator(); $entityGenerator->setGenerateAnnotations(true); $entityGenerator->setGenerateStubMethods(true); $entityGenerator->setRegenerateEntityIfExists(true); $entityGenerator->setUpdateEntityIfExists(false); $entityGenerator->generate($metadata, __DIR__); echo "Entities created"; 

Хотя установка значения в конструкторе будет работать, использование событий жизненного цикла Doctrine может быть лучшим решением.

Используя событие prePersist Lifecycle Event, вы можете установить значение по умолчанию для своей сущности только при первоначальном сохранении.

Будьте внимательны при настройке значений по умолчанию для определения свойств! Вместо этого сделайте это в конструкторе, чтобы сохранить его без проблем. Если вы определяете его по определению свойства, то сохраняйте объект в базе данных, затем выполняйте частичную загрузку, а затем не загруженные свойства снова будут иметь значение по умолчанию. Это опасно, если вы хотите снова сохранить объект.