Как установить значение по умолчанию в Doctrine 2?
Как установить значение по умолчанию в Doctrine 2?
Ответы:
Значения по умолчанию для базы данных не поддерживаются. Единственный способ использовать значения по умолчанию для базы данных - использовать columnDefinitionатрибут сопоставления, в котором вы указываете SQLфрагмент ( DEFAULTвключающий причину) для столбца, в который отображается поле.
Ты можешь использовать:
<?php
/**
* @Entity
*/
class myEntity {
/**
* @var string
*
* @Column(name="myColumn", type="string", length="50")
*/
private $myColumn = 'myDefaultValue';
...
}
Значения по умолчанию на уровне PHP предпочтительнее, поскольку они также правильно доступны для вновь создаваемых и сохраняемых объектов (Doctrine не вернется в базу данных после сохранения нового объекта для получения значений по умолчанию).
<?php
/**
* @Entity
*/
class myEntity {
/**
* @var string
*
* @ORM\Column(name="myColumn", type="integer", options={"default" : 0})
*/
private $myColumn;
...
}
Обратите внимание, что здесь используется SQL DEFAULT, который не поддерживается для некоторых полей, таких как BLOBи TEXT.
options={"default": 0}будьте осторожны, используя «а не», так как это вызывает ошибки в моей версии доктрины.
Установите конструктор в вашей сущности и установите там значение по умолчанию.
Использование:
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.
Ни один из предыдущих ответов не помог мне с моим конкретным сценарием, но я нашел решение.
У меня было поле формы, которое должно было вести себя следующим образом:
Затем я попробовал все рекомендации, приведенные здесь. Позвольте мне перечислить их:
<?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->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');
}
if (!$this->getDtPosted()) { $this->setDtPosted(new \DateTime()); }
Вы можете сделать это, используя 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>
Вот как я решил это для себя. Ниже приведен пример 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'
columnDefinitionидет прямо против цели наличия ORM, который является абстракцией от базы данных. Это решение нарушит мобильность, сохранит зависимость вашего программного обеспечения от поставщика БД, а также сломает инструменты Doctrine Migrations.
У меня работает и в базе данных mysql:
Entity\Entity_name:
type: entity
table: table_name
fields:
field_name:
type: integer
nullable: true
options:
default: 1
Ничто из этого не сработало для меня. Я нашел некоторую документацию на сайте доктрины, в которой говорится, чтобы установить значение напрямую, чтобы установить значение по умолчанию.
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
$entity->setFieldName()перед промывкой? Doctrine, похоже, определяет значение по умолчанию в null. Единственное решение в yaml - определить значение по умолчанию В классе сущностей, которое мне кажется глупым, поскольку оно уже определено в yaml ... -_-
Я боролся с той же проблемой. Я хотел получить значение по умолчанию из базы данных в сущности (автоматически). Угадай что, я сделал это :)
<?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событие жизненного цикла, вы можете установить значение по умолчанию для вашей сущности только при первоначальном сохранении.
hack. Никогда не полагайтесь на хаки.
Будьте осторожны при установке значений по умолчанию при определении свойства! Вместо этого сделайте это в конструкторе, чтобы сохранить его без проблем. Если вы определите его в определении свойства, затем сохраните объект в базе данных, затем выполните частичную загрузку, тогда незагруженные свойства снова будут иметь значение по умолчанию. Это опасно, если вы хотите сохранить объект снова.