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 02/02/2011, 10h35   #1
Nouveau Membre du Club
 
Homme
Étudiant
Inscription : août 2006
Messages : 49
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Santé

Informations forums :
Inscription : août 2006
Messages : 49
Points : 25
Points : 25
Par défaut $object->save() : changement de comportement add/update

Bonjour,

J'ai un formulaire dont je surcharge la méthode save() pour effectuer un traitement des données : ou bien un objet similaire existe déjà dans la table (comparaison sur quelques champs) et alors on met à jour l'entrée existante, ou bien cette recherche ne retourne aucun objet similaire et on l'ajoute à la base.

Je pourrais donc me contenter d'un (en pseudo-code) :
Code :
1
2
3
4
if($exist = $this->searchObject($object))
  return $this->updateExistingObject($exist); // renvoie sur un Doctrine_Query
else
  return parent::save($conn);
Mais je n'aime pas cette étape qui zappe parent::save()... Du coup, je me demandais si en éditant les propriétés de l'objet lui même, on pouvait changer la requète d'ajout en requête d'update. J'ai essayé de simplement faire correspondre l'id de l'objet à celui en base, bien heureusement Symfony me signale un doublon. J'ai aussi naïvement essayé de réassigner l'objet de la base à $this... vous vous doutez du résultat.

Bref je voulais savoir si vous connaissiez une manière propre de le faire (peut-être en dehors de save() du coup) ou si mon update séparé du départ reste la meilleure solution même si elle ne passe plus par parent::save().
CaraG33k est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2011, 12h07   #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
A vue de nez, et sans avoir creuser la solution.

Ta proposition me semble raisonnable et très dans le style de framework. Par contre, elle ne me semble pas du tout coller avec le modèle objet de Doctrine et donc me semble irréalisable.

En effet, dans l'idée de Doctrine, tu prends un objet dans la base (ou tu en crée un nouveau), tu y apportes les modifications nécessaires et tu sauvegardes (que se soit un nouveau ou un ancien).

Hors toi tu voudrais partir d'un objet "indéfini" qui devra choisir sa manière d'exister, soit je suis nouveau, soit je me sauvegarde, tu vas donc largement à l'encontre du fonctionnement intrinsèque de Doctrine.

Je pense que le plus simple sera, dans ton contrôleur, de vérifier avant de charger l'objet doctrine. En pseudo code, dans le contrôleur, cela va donner :
Code Pseudocode :
1
2
3
4
5
6
7
8
9
10
 
Si ObjetExist
     enregistrement = ChargeObjetDoctrine NuméroObjet
Sinon
     enregistrement = CréeObjetDoctrine 
FinSi
 
enregistrement->setDonnee1($Donnee1)
....
enregistrement->save()
A noter que le si du départ peut se faire simultanément à la récupération de l'enregistrement, si la requête ne retourne rien, l'objet sera null qu'il restera à tester. Avantage, un seul accès à la BDD.
__________________
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 02/02/2011, 16h30   #3
Nouveau Membre du Club
 
Homme
Étudiant
Inscription : août 2006
Messages : 49
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant
Secteur : Santé

Informations forums :
Inscription : août 2006
Messages : 49
Points : 25
Points : 25
De ce que tu me dis, je comprends que si on crée un objet (par défaut dans mon cas), Doctrine n'utilise pas la même classe d'objet que si on le modifie, c'est bien ça ? Du coup pas de méthode/valeur possiblement modifiable pour passer de l'un à l'autre et nécessité de déclarer ce que l'on veut faire à l'instanciation. J'ai bon ?

Le hic, c'est que je ne peux pas le définir à la création du formulaire : des objets existent, l'utilisateur donne des informations valides pour créer un objet, cet objet peut faire partie des objets existants, ou pas. Du coup, peut-être effectivement un test lors de l'action Create correspondante et définir $this->form en fonction (à la manière du $this->forward404Unless() que l'on retrouve classiquement dans les éditions d'objet).
CaraG33k est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2011, 17h16   #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
Non, ce que je dis c'est qu'un objet Doctrine correspond à un enregistrement précis. Pas soit l'un soit l'autre. Du moins pas facilement et ce n'est pas le comportement prévu.

Mais tu peux parfaitement faire, avec un peu de travail en plus, un form non lié à doctrine, l’alimenter, le récupérer, vérifier les saisie, décider ce que tu fais des données, soit récupérer soit nouveau, mettre les données et enregistrer.

Tu pourrais probablement créer une classe dans le genre de la sfFormDoctrine qui va gérer cela directement, mais si tu n'as qu'un form à gérer je pense que c'est une perte de temps. Plus propre (quoique) mais beaucoup plus long, sauf si tu connais parfaitement la structure des objets form.
__________________
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 07h27.


 
 
 
 
Partenaires

Hébergement Web