Précédent   Forum des professionnels en informatique > PHP > Bibliothèques et frameworks > symfony
symfony Forum d'entraide sur le framework PHP symfony. Avant de poster : cours symfony et FAQ symfony
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 12/04/2011, 09h43   #1
Invité de passage
 
Inscription : mai 2010
Messages : 7
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 7
Points : 1
Points : 1
Par défaut Créer un formulaire imbriqué "à l'envers"

Bon, le titre n'est pas très clair, alors je m'explique un peu

Voici mon schéma (très simplifié)

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
Abonnements:
  connection: doctrine
  tableName: abonnements
  columns:
    abonnement_id:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: true
      autoincrement: true
    abonnement_commande_id:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: false
      notnull: false      
      autoincrement: false      
    abonnement_creation_date:
      type: timestamp(25)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    abonnement_last_update:
      type: timestamp(25)
      fixed: false
      unsigned: false
      primary: false
      default: '0000-00-00 00:00:00'
      notnull: true
      autoincrement: false
    abonnement_credit:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: false
      default: '0'
      notnull: true
      autoincrement: false
    abonnement_statut:
      type: enum(9)
      fixed: false
      unsigned: false
      values:
        - PAYEMENT A LA RECEPTION
        - ACCOMPTE
        - PAYE
        - NON PAYE
      primary: false
      default: 'PAYEMENT A LA RECEPTION'
      notnull: true
  relations:
    Commandes:
      local: abonnement_id
      foreign: commande_abonnement_id
      type: many
Commandes:
  connection: doctrine
  tableName: commandes
  columns:
    commande_id:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: true
    commande_date:
      type: timestamp(25)
      fixed: false
      unsigned: false
      default: NOW()
      primary: false
      notnull: true
      autoincrement: false
    commande_abonnement_id:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: false
      notnull: false
      autoincrement: false
  relations:
    Abonnements:
      local: commande_abonnement_id
      foreign: abonnement_id
      type: one
J'ai fais un unset sur les champs non utilisés de mon formulaire abonnement
Dans mon commandeForm j'avais placé ceci:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
$this->embedRelations(array(
  'Abonnement' => array(
  	'considerNewFormEmptyFields'    => array('abonnement_credit', 'abonnement_statut'),
  	'noNewForm'                     => false,
	'newFormLabel'                  => '<br /><i>Abonnement</i>',
    'newFormClassArgs'              => array(array('sf_user' => $this->getOption('sf_user'))),
    'displayEmptyRelations'         => true,
    'formClassArgs'                 => array(array('ah_add_delete_checkbox' => false)),
    'newFormAfterExistingRelations' => true,
    'formFormatter'                 => null,
    'multipleNewForms'              => false,
    'newFormsInitialCount'          => 1,
    'newFormsContainerForm'         => null, // pass BaseForm object here or we will create ahNewRelationsContainerForm
    'newRelationButtonLabel'        => '+',
    'newRelationAddByCloning'       => true,
    'newRelationUseJSFramework'     => 'jQuery',
    'customEmbeddedFormLabelMethod' => 'getLabelTitle',
  )
));
Un abonnement peut être lié à plusieurs commandes.
Dans la table abonnement, j'ai un champ abonnement_commande_id
Ce champ n'est pas vraiment nécessaire dans la relation, il permet simplement de lier l'abonnement à une commande de "référence". J'ai effacé la relation de mon schéma en me demandant si le problème venait de là, mais il semblerait que non

Pour résumer, un abonnement possède une commande de référence et plusieurs commandes peuvent se référer à cet abonnement (en fait, ces commandes seront insérées automatiquement, en prenant pour modèle la commande référencée dans l'abonnement)

J'aimerais pouvoir intégrer le formulaire d'abonnement dans le formulaire de création de commande (un formulaire simple, pas un formulaire de l'admin autogénéré). Et c'est là que ça pose problème, car doctrine ne reconnait pas le lien dans ce sens (je pense).

J'ai déjà fais des formulaire imbriqué (avec ahDoctrineEasyEmbeddedRelationsPlugin) , mais dans l'autre sens, c'est à dire que dans le cas présent il faudrait inclure le formulaire commande dans le formulaire abonnement.... ce qui ne me va pas du tout.

donc je dois faire un formulaire imbriqué dans le sens n ==> 1 à la place de le faire dans le sens 1 ==> n

Auriez vous une idée?

Merci d'avance
morfessa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/04/2011, 11h39   #2
Modérateur
 
Avatar de Michel Rotta
 
Homme Michel Rotta
Responsable d'exploitation informatique
Inscription : septembre 2005
Messages : 4 913
Détails du profil
Informations personnelles :
Nom : Homme Michel Rotta
Âge : 49
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Responsable d'exploitation informatique
Secteur : Distribution

Informations forums :
Inscription : septembre 2005
Messages : 4 913
Points : 7 505
Points : 7 505
Le shema.yml revu "à ma façon".
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 
Abonnement:
  connection: doctrine
  tableName: abonnements
  actAs:
    timestampable: ~
  columns:
    commande_id: integer #Quel intérêt ???
    credit:
      type: integer(4)
      unsigned: true
      default: '0'
      notnull: true
    statut:
      type: enum(9)
      values:
        - PAYEMENT A LA RECEPTION
        - ACCOMPTE
        - PAYE
        - NON PAYE
      default: 'PAYEMENT A LA RECEPTION'
      notnull: true
 
Commande:
  connection: doctrine
  tableName: commandes
  columns:
    date:
      type: timestamp
      default: NOW()
      notnull: true
    abonnement_id:
      type: integer
      unsigned: true
  relations:
    Abonnement:
      foreignAlias: Commandes
  • Le nom des objets est toujours au singulier. Il représente un abonnement.
  • La clef unique de la table s'appelle "id" et est automatiquement crée par doctrine si rien n'est précisé (type integer auto-incrementé)
  • préciser pour chaque champ de la table qu'il fait partie de la table dans le nom de champ ne sert qu'à alourdir inutilement le schéma objet généré.
  • le behavior timestampable génère et gère automatiquement les champs date de création et de mise à jour.
  • Le type enum gagne à ne surtout pas être utilisé. Il demande à être redéfini dans le modèle et le moindre changement d'état nécessite une modification du modèle symfony et de la base. Il est plus simple de gérer un integer et de créer dans le modèle un getStatutTypes qui retourne un array des types, qui pourra être alégrement utilisé dans les widget et validateur du form.
  • La relation "1-n" n'est définie que sur un de ces côté, généralement le "n"
  • Si un abonnement peut générer plusieurs commandes que comptes-tu mettre dans le champ commande_id de la table abonnement ???

Le embed est conçu pour être lié d'une table "1" d'une relation "1-n" vers les tables "n". Pas le contraire (éventuellement d'un 1 vers un 1 d'une relation "1-1" mais il y a un autre plus spécifique pour cela).

Le embed ne fonctionne pas correctement si l'enregistrement 1 n'a pas été sauvegardé avant la génération de l'écran. Donc en gros, lors de la création d'un enregistrement avec des embed il faut désactiver les embed.
__________________
Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).
  • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
  • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
  • Une discussion est terminée ? Alors le bouton est votre ami !
Michel Rotta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/04/2011, 09h14   #3
Invité de passage
 
Inscription : mai 2010
Messages : 7
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 7
Points : 1
Points : 1
Citation:
* Le nom des objets est toujours au singulier. Il représente un abonnement.
* La clef unique de la table s'appelle "id" et est automatiquement crée par doctrine si rien n'est précisé (type integer auto-incrementé)
* préciser pour chaque champ de la table qu'il fait partie de la table dans le nom de champ ne sert qu'à alourdir inutilement le schéma objet généré.
En fait j'ai généré le schéma à partir d'une table déjà créée, mais je vais penser à faire un refactoring de la table..


Citation:
* le behavior timestampable génère et gère automatiquement les champs date de création et de mise à jour.
C'est vrai que je n'ai pas ce réflexe, je vais le faire de suite

Citation:
* Le type enum gagne à ne surtout pas être utilisé. Il demande à être redéfini dans le modèle et le moindre changement d'état nécessite une modification du modèle symfony et de la base. Il est plus simple de gérer un integer et de créer dans le modèle un getStatutTypes qui retourne un array des types, qui pourra être alégrement utilisé dans les widget et validateur du form.
Je change également tout de suite, surtout que je m'étais déjà fais la réflexion

Citation:
* La relation "1-n" n'est définie que sur un de ces côté, généralement le "n"
* Si un abonnement peut générer plusieurs commandes que comptes-tu mettre dans le champ commande_id de la table abonnement ???
Le champ commande_id de la table abonnement reprend en fait la commande "modèle" de l'abonnement, c'est cette commande qui sera reproduite chaque mois



Conseillerais tu une methode particulière pour pouvoir créer la commande modèle et l'enregistrement "abonnement" associé?

Je pourrais permettre la création de la commande et de l'abonnement séparé, (tout en devant sélectionner la commande référence lorsque l'on crée l'abonnement), mais ça fait lourd comme solution...

merci pour ta réponse en tout cas ^^
morfessa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/04/2011, 12h59   #4
Modérateur
 
Avatar de Michel Rotta
 
Homme Michel Rotta
Responsable d'exploitation informatique
Inscription : septembre 2005
Messages : 4 913
Détails du profil
Informations personnelles :
Nom : Homme Michel Rotta
Âge : 49
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Responsable d'exploitation informatique
Secteur : Distribution

Informations forums :
Inscription : septembre 2005
Messages : 4 913
Points : 7 505
Points : 7 505
D'une manière général et sauf contraintes liées à de l'existant il vaut mieux partir d'un shema.yml pour arriver à une base de données que le contraire, en effet le shema.yml est plus que la simple description des tables.

Citation:
Le champ commande_id de la table abonnement reprend en fait la commande "modèle" de l'abonnement, c'est cette commande qui sera reproduite chaque moi
A la lacture du schéma ce n'était pas claire. Alors il faut définir deux relations, une 1-n tel que déjà définie et un 1-1 entre ce chaps est la commande type.

Citation:
Conseillerais tu une methode particulière pour pouvoir créer la commande modèle et l'enregistrement "abonnement" associé?
Il n'y a pas de bonne méthode pour créer ces deux élément simultanément. Le plus simple consiste à créer l'enregistrement maître et les enregistrements enfants ensuite. Ici le problème est que chacun des deux enregistrement est simultanément maître et enfant...

Je pense qu'il faut que tu supprimes les contraintes sur les clef (notnull: true), que tu crées dans un form non relié à doctrine (parent sfWebForm) tes données et que tu traites "à la main" dans ton contrôleur la création des deux enregistrements puis leurs liaisons respectives.
__________________
Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).
  • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
  • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
  • Une discussion est terminée ? Alors le bouton est votre ami !
Michel Rotta est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 02h45.


 
 
 
 
Partenaires

Hébergement Web