name column php orm doctrine2

php - column - Valor por defecto en Doctrine



orm column name (15)

¿Cómo establezco un valor predeterminado en Doctrine 2?


Actualizar

Una razón más por la que leer la documentación de Symfony nunca pasará de moda. Existe una solución simple para mi caso específico y es establecer la opción de field type empty_data en un valor predeterminado.

Una vez más, esta solución es solo para el escenario donde una entrada vacía en un formulario establece el campo DB en nulo.

Fondo

Ninguna de las respuestas anteriores me ayudó con mi escenario específico, pero encontré una solución.

Tenía un campo de formulario que necesitaba comportarse como sigue:

  1. No es necesario, se puede dejar en blanco. (Usado ''requerido'' => falso)
  2. Si se deja en blanco, debería predeterminarse a un valor dado. Para una mejor experiencia de usuario, no establecí el valor predeterminado en el campo de entrada, sino que utilicé el atributo html ''marcador de posición'', ya que es menos molesto.

Entonces probé todas las recomendaciones dadas aquí. Déjame enumerarlos:

  • Establecer un valor predeterminado cuando para la propiedad de la entidad:

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

  • Utilice la anotación de opciones:

@ORM/Column(name="foo", options={"default":"foo bar"})

  • Establecer el valor predeterminado en el constructor:

/** * @Entity */ class myEntity { ... public function __construct() { $this->myColumn = ''myDefaultValue''; } ... } Nada de eso funcionó y todo debido a cómo Symfony usa tu clase de Entidad.

IMPORTANTE

Los campos de formulario de Symfony anulan los valores predeterminados establecidos en la clase Entidad. Es decir, su esquema para su base de datos puede tener un valor predeterminado definido, pero si deja un campo no obligatorio vacío al enviar su formulario, form->handleRequest() dentro de su método form->isValid() anulará esos valores predeterminados en su clase de Entity y establecerlos en los valores de campo de entrada. Si los valores del campo de entrada están en blanco, establecerá la propiedad Entity en null .

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

Mi solución

Establezca el valor predeterminado en su controlador después de form->handleRequest() dentro de su método form->isValid() :

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

No es una solución hermosa pero funciona. Probablemente podría hacer un validation group pero puede haber personas que vean este problema como una transformación de datos en lugar de una validación de datos , dejo que usted lo decida.

Anular Setter (no funciona)

También intenté anular el establecedor de entidades de esta manera:

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

Esto, aunque se ve más limpio, no funciona . La razón es que el malvado form->handleRequest() no usa los métodos de establecimiento del Modelo para actualizar los datos ( form->setData() en form->setData() para más detalles).


¡Tenga cuidado al configurar los valores predeterminados en la definición de propiedad! Hágalo en el constructor en su lugar, para mantenerlo libre de problemas. Si lo define en la definición de propiedad, entonces persiste el objeto en la base de datos, luego realice una carga parcial, entonces las propiedades no cargadas tendrán nuevamente el valor predeterminado. Eso es peligroso si quieres persistir el objeto de nuevo.


Añadiendo a @romanb brillante respuesta.

Esto agrega un poco de sobrecarga en la migración, porque obviamente no puede crear un campo sin restricción nula y sin valor predeterminado.

// 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");

Con esta respuesta, lo aliento a pensar, ¿por qué necesita el valor predeterminado en la base de datos en primer lugar? Y por lo general es permitir crear objetos sin restricción nula.


Aquí es cómo lo resolví por mí mismo. A continuación se muestra un ejemplo de entidad con valor predeterminado para MySQL. Sin embargo, esto también requiere la configuración de un constructor en su entidad, y para que establezca el valor predeterminado allí.

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''


Configure un constructor en su entidad y establezca el valor predeterminado allí.


Funciona para mí en una base de datos mysql también:

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


La solución que utilicé fue un LifeCycleCallback . Todavía @Column(type="string", default="hello default value") esperando a ver si hay más métodos "nativos", por ejemplo, @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''); }


Luché con el mismo problema. Quería tener el valor predeterminado de la base de datos en las entidades (automáticamente). Adivina qué, lo hice :)

<?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";



Puedes hacerlo usando xml también:

<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>


Si bien la configuración del valor en el constructor funcionaría, usar los eventos del ciclo de vida de Doctrine podría ser una mejor solución.

Al aprovechar el Evento de ciclo de vida prePersist , puede establecer su valor predeterminado en su entidad solo en la persistencia inicial.


Si usa la definición yaml para su entidad, lo siguiente funciona para mí en una base de datos postgresql:

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


Utilizar:

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

y no:

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

Por ejemplo:

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


Los valores predeterminados de la base de datos no son compatibles de manera "portátil". La única forma de usar los valores predeterminados de la base de datos es a través del columnDefinition asignación columnDefinition donde se especifica el fragmento de columnDefinition SQL ( DEFAULT causa inclusive) para la columna a la que se asigna el campo.

Puedes usar:

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

Se prefieren los valores predeterminados a nivel de PHP, ya que también están disponibles de manera adecuada en los objetos creados recientemente y persistentes (Doctrine no regresará a la base de datos después de persistir un nuevo objeto para obtener los valores predeterminados).


<?php /** * @Entity */ class myEntity { /** * @var string * * @ORM/Column(name="myColumn", type="integer", options={"default" : 0}) */ private $myColumn; ... }

Tenga en cuenta que esto utiliza SQL DEFAULT , que no es compatible con algunos campos como BLOB y TEXT .