368 votes

Valeur par défaut dans Doctrine

Comment puis-je définir une valeur par défaut dans Doctrine 2 ?

27 votes

@ORM \Column (name="foo", type="decimal", precision=7, scale=2, options={"default" = 0}) fonctionne (à partir de la réponse non populaire ci-dessous)

4 votes

@ORM \Column (name="is_activated", type="boolean",options={"default":0}) OR @ORM \Column (name="is_activated", type="boolean",options={"default"= 0})

0 votes

Ahmed, cela ne semble pas fonctionner pour les booléens dans Symfony 2.3. Cependant, options={"default" = "0"}) fonctionne, en mettant le nombre entier entre guillemets.

628voto

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

Notez que cela utilise SQL DEFAULT ce qui n'est pas possible pour certains champs comme BLOB y TEXT .

5 votes

Bien vu ! Il semble qu'il n'y ait pas d'option options={"default" = 0} dans la documentation officielle.

2 votes

Pour info, le options est également utile pour unsigned valeurs. voir ceci réponse

0 votes

Très bien ! C'est très utile en outre d'avoir des valeurs par défaut en PHP (selon la réponse acceptée) lorsque vous migrez entre des versions de modèles et que vous ne voulez pas que des entités préexistantes obtiennent une valeur nulle pour un champ nouvellement ajouté !

416voto

romanb Points 2602

Les valeurs par défaut des bases de données ne sont pas "portables". La seule façon d'utiliser les valeurs par défaut des bases de données est de passer par la fonction columnDefinition où vous spécifiez l'attribut de mappage SQL extrait ( DEFAULT inclusivement) pour la colonne à laquelle le champ est associé.

Vous pouvez utiliser :

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

Les valeurs par défaut au niveau PHP sont préférables car elles sont également disponibles sur les objets nouvellement créés et persistés (Doctrine ne retournera pas à la base de données après avoir persisté un nouvel objet pour obtenir les valeurs par défaut).

11 votes

Mais il y a un problème ici : Que se passe-t-il si je définis un type "datetime" ?

48 votes

@artragis met votre instanciation dans le constructeur d'entité

19 votes

Il faut être prudent avec les migrations utilisant cette approche, car toute rangée existante fera échouer la migration.

65voto

Jeremy Hicks Points 1841

Créez un constructeur dans votre entité et définissez-y la valeur par défaut.

0 votes

Cela semble être l'approche logique. Quelqu'un a-t-il rencontré des problèmes avec la mise en place de valeurs par défaut dans le constructeur ?

26 votes

La solution recommandée par Doctrine : doctrine-project.org/docs/orm/2.1/en/reference/faq.html

0 votes

@cantera25 cela devrait être la réponse +1

58voto

Utilisez :

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

et non :

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

Par exemple :

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

2 votes

Je suis désolé, vous avez raison. Vous pouvez donc trouver une explication sur cette page : doctrine-formulaire annotations-référence

1 votes

Le lien dans le commentaire ci-dessus est mort. Essayez celui-ci .

57voto

Callistino Points 369

Mise à jour

Une raison de plus pour laquelle lire la documentation pour Symfony ne sera jamais démodée. Il y a une solution simple pour mon cas spécifique et c'est de mettre le paramètre field type option empty_data à une valeur par défaut.

Encore une fois, cette solution ne concerne que le scénario dans lequel une entrée vide dans un formulaire donne la valeur null au champ de la base de données.

Contexte

Aucune des réponses précédentes ne m'a aidé dans mon scénario spécifique mais j'ai trouvé une solution.

J'avais un champ de formulaire qui devait se comporter comme suit :

  1. Non requis, peut être laissé en blanc. (Utilisé 'required' => false)
  2. Si elle est laissée vide, elle doit être remplacée par une valeur par défaut. Pour une meilleure expérience utilisateur, je n'ai pas défini la valeur par défaut du champ de saisie, mais j'ai plutôt utilisé l'attribut html 'placeholder', car il est moins gênant.

J'ai ensuite essayé toutes les recommandations données ici. Permettez-moi de les énumérer :

  • Définit une valeur par défaut pour la propriété de l'entité :

    <?php /**

    • @Entity */ class myEntity { /**
      • @var string
      • @Column(name="myColumn", type="string", length="50") */ private $myColumn = 'myDefaultValue'; ... }
  • Utilisez l'annotation "options" :

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

  • Définit la valeur par défaut sur le constructeur :

    /**

    • @Entity */ class myEntity { ... public function __construct() { $this->myColumn = 'myDefaultValue'; } ... }

Rien de tout cela n'a fonctionné et tout cela à cause de la façon dont Symfony utilise votre classe Entity.

IMPORTANT

Les champs de formulaire Symfony remplacent les valeurs par défaut définies dans la classe Entity. En d'autres termes, le schéma de votre base de données peut définir une valeur par défaut, mais si vous laissez un champ non obligatoire vide lors de l'envoi de votre formulaire, le système de gestion de l'information de la base de données de l'Union européenne (UE) sera activé. form->handleRequest() à l'intérieur de votre form->isValid() remplacera ces valeurs par défaut dans votre Entity et de les définir comme les valeurs des champs de saisie. Si les valeurs du champ de saisie sont vides, la classe Entity à la propriété null .

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

Ma solution de rechange

Définissez la valeur par défaut sur votre contrôleur après form->handleRequest() à l'intérieur de votre form->isValid() méthode :

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

Ce n'est pas une belle solution mais elle fonctionne. Je pourrais probablement faire un validation group mais il y a peut-être des gens qui voient cette question comme une transformation de données plutôt que validation des données Je vous laisse le soin de décider.


Override Setter (ne fonctionne pas)

J'ai également essayé de remplacer le Entity de cette façon :

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

    return $this;
}
...

Ceci, même si ça a l'air plus propre, ça ne marche pas . La raison étant que le mal form->handleRequest() n'utilise pas les méthodes setter du modèle pour mettre à jour les données (voir la section form->setData() pour plus de détails).

0 votes

Cette réponse devrait figurer en tête de liste, c'est certain. Le composant de formulaire utilise PropertyAccessor pour obtenir et définir les valeurs de vos propriétés. Peut-être que l'accesseur de propriété devrait utiliser les méthodes lorsqu'elles sont disponibles ?

1 votes

Les colonnes booléennes ne supportent pas les valeurs par défaut de php, donc seulement les annotations.

0 votes

C'est la seule solution qui fonctionne lorsque les informations proviennent de formulaires. Je ne suis pas non plus d'accord avec les commentaires ci-dessus concernant les booléens. Ils n'acceptent pas l'annotation par défaut.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X