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



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

972   15  

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.

фон

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

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

  1. не требуется, может быть оставлено пустым. (Используется 'required' = > false)
  2. если оставить пустым, то по умолчанию заданное значение. Для лучшего пользовательского опыта я не устанавливал значение по умолчанию в поле ввода, а скорее использовал атрибут 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"})
  • установить значение по умолчанию в конструкторе:
/**
 * @Entity
 */
class myEntity {
    ...
    public function __construct()
    {
        $this->myColumn = 'myDefaultValue';
    }
    ...
}
Ничего из этого не сработало, и все из-за того, как Symfony использует ваш класс сущностей.

важно

поля формы 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

    Ничего не найдено.