15 ответов:
значения по умолчанию базы данных не поддерживаются" переносимо". Единственный способ использовать значения по умолчанию базы данных через
columnDefinitionатрибут сопоставления, где вы укажитеSQLфрагмент (DEFAULTпричина включительно) для столбца, к которому сопоставлено поле.вы можете использовать:
<?php /** * @Entity */ class myEntity { /** * @var string * * @Column(name="myColumn", type="string", length="50") */ private $myColumn = 'myDefaultValue'; ... }значения по умолчанию на уровне PHP предпочтительны, так как они также правильно доступны на вновь созданных и сохраненных объектах (доктрина не вернется в базу данных после сохранения нового объект для получения значений по умолчанию).
<?php /** * @Entity */ class myEntity { /** * @var string * * @ORM\Column(name="myColumn", type="integer", options={"default" : 0}) */ private $myColumn; ... }обратите внимание, что это использует 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значение по умолчанию.опять же, это решение предназначено только для сценария, где пустой вход в форме устанавливает поле DB в null.
фон
ни один из предыдущих ответов не помог мне с моим конкретным сценарием, но я нашел решение.
у меня было поле формы, которое должно было вести себя следующим образом:
- не требуется, может быть оставлено пустым. (Используется 'required' = > false)
- если оставить пустым, то по умолчанию заданное значение. Для лучшего пользовательского опыта я не устанавливал значение по умолчанию в поле ввода, а скорее использовал атрибут html "заполнитель", поскольку он менее навязчив.
затем я попробовал все рекомендации, данные здесь. Позвольте мне перечислить они:
- установите значение по умолчанию, когда для свойства сущности:
<?php /** * @Entity */ class myEntity { /** * @var string * * @Column(name="myColumn", type="string", length="50") */ private $myColumn = 'myDefaultValue'; ... }
- используйте аннотации, варианты:
@ORM\Column(name="foo", options={"default":"foo bar"})
- установить значение по умолчанию в конструкторе:
Ничего из этого не сработало, и все из-за того, как Symfony использует ваш класс сущностей./** * @Entity */ class myEntity { ... public function __construct() { $this->myColumn = 'myDefaultValue'; } ... }важно
поля формы Symfony переопределяют значения по умолчанию, установленные в классе сущностей. То есть, ваш схемы БД может иметь значение по умолчанию, но если вы оставите необязательное поле пустым при отправке формы
form->handleRequest()внутриform->isValid()метод переопределить эти значения по умолчанию на вашемEntityкласс и установить их на значения полей ввода. Если значения входного поля пусты, то он установитEntityсвойствоnull.http://symfony.com/doc/current/book/forms.html#handling-form-submissions
мой Обходной путь
установить значение по умолчанию на контроллере после
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->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('Y-m-d 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
вот как я решил это для себя. Ниже приведен пример сущности со значением по умолчанию для 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'
ничего из этого не работает для меня. Я нашел некоторую документацию на сайте doctrine, в которой говорится, чтобы установить значение напрямую, чтобы установить значение по умолчанию.
http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/faq.html
private $default = 0;это вставило значение, которое я хотел.
Если вы используете определение yaml для своей сущности, для меня в базе данных postgresql работает следующее:
Entity\Entity_name: type: entity table: table_name fields: field_name: type: boolean nullable: false options: default: false
добавление к @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");С этим ответом, я призываю вас подумать зачем вам значение по умолчанию в базе данных в первую очередь? И обычно это позволяет создавать объекты с не нулевым ограничением.
Я боролся с той же проблемой. Я хотел иметь значение по умолчанию из базы данных в объекты (автоматически). Угадайте, что я сделал:)
<?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";
хотя установка значения в конструкторе будет работать, использование событий жизненного цикла доктрины может быть лучшим решением.
используя
prePersistсобытие жизненного цикла, вы можете установить значение по умолчанию для вашего объекта только при первоначальном сохранении.
будьте внимательны при установке значений по умолчанию на определение свойства! Сделайте это в конструкторе вместо этого, чтобы сохранить его без проблем. Если вы определяете его в определении Свойства, затем сохраняете объект в базе данных, а затем выполняете частичную загрузку, то не загруженные свойства снова будут иметь значение по умолчанию. Это опасно, если вы хотите сохранить объект.
Comments