[cakephp] Question de noob sur les models

Question de noob sur les models [cakephp] - PHP - Programmation

Marsh Posté le 03-02-2015 à 14:27:59    

Hello tout le monde, j'ai un gros problème avec cakephp et je sent que je vais péter une pile  :fou:  
 
Pour faire simple, j'ai 2 tables A et B
 

as
===
id
name
b1_id
b2_id


 
et  
 

bs
====
id
name


 
avec les relations

A.b1_id => B.id

et

A.b2_id => B.id


 
sous mysql, mes tables s'appellent 'as' et 'bs' pour respecter les conventions cakephp
 
Dans les tables, j'ai :
 

as
=====
1 - Ligne A1 - 1 - 2
2 - Ligne A2 - 2 - 3
3 - Ligne A3 - 3 - 4
4 - Ligne A4 - 4 - 5


 

bs
=====
1 - Ligne B1
2 - Ligne B2
3 - Ligne B3
4 - Ligne B4
5 - Ligne B5


 
 
J'ai fais mes controllers, mes views, et je voudrais juste que ca marche !!!,  
 
Genre pour un

/A/view/3

, ca marche, mais j'ai l'impression que j'ai fais du bricolage :whistle:, si qqn pouvait me dire si c'est juste ?
 

Modèle : A.php:


 

Code :
  1. <?php
  2. class A extends AppModel {
  3.   public $name = 'A';
  4.   public $hasOne= array('B1' => array( 'className' => 'B',
  5.                          'foreignKey' => false,
  6.                          'conditions' => array('A.b1_id = B1.id')
  7.                                       )
  8.                         ,
  9.                         'B2' => array( 'className' => 'B',
  10.                         'foreignKey' => false,
  11.                          'conditions' => array('A.b2_id = B2.id')
  12.                                     )
  13.                         );
  14. }


 
ca me retourne  
 

Code :
  1. Array
  2. (
  3.     [A] => Array
  4.         (
  5.             [id] => 3
  6.             [name] => Ligne A3
  7.             [b1_id] => 3
  8.             [b2_id] => 4
  9.         )
  10.      [B1] => Array
  11.         (
  12.             [id] => 3
  13.             [name] => Ligne B3
  14.         )
  15.      [B2] => Array
  16.         (
  17.             [id] => 4
  18.             [name] => Ligne B4
  19.         )
  20. )


Ce qui est plutot pas mal.  
 
Par contre, dans le sens B vers A, mon belongsTo fait de la merde  :cry:  
 

Modèle B.php


Code :
  1. <?php
  2. class B extends AppModel {
  3.   public $name = 'B';
  4.   public $belongsTo = array('A' => array(
  5.                                   'className' => 'A',
  6.                                   'foreignKey' => false,
  7.                                   'conditions' => 'A.b1_id = B.id OR A.b2_id = B.id'
  8.                                   )
  9.   );
  10. }


Dans le controller view de B, je fais un

Code :
  1. set('data', $this->B->findById($id));


 

/B/view/3


Ca me donne ca:

Code :
  1. Array
  2. (
  3.     [B] => Array
  4.         (
  5.             [id] => 3
  6.             [name] => Ligne B3
  7.         )
  8.      [A] => Array
  9.         (
  10.             [id] => 2
  11.             [name] => Ligne A2
  12.             [b1_id] => 2
  13.             [b2_id] => 3
  14.         )
  15. )


 
Dans DebugKit :
 

Code :
  1. SELECT `B`.`id`, `B`.`name`, `A`.`id`, `A`.`name`, `A`.`b1_id`, `A`.`b2_id` FROM `ma_base`.`bs` AS `B` LEFT JOIN `ma_base`.`as` AS `A` ON (`A`.`b1_id` = `B`.`id` OR `A`.`b2_id` = `B`.`id`) WHERE `B`.`id` = 3 LIMIT 1


 
mais je ne récupère qu'une ligne (normal avec le limit 1)  
 
Alors que je voudrais toutes les lignes de A associés !!
 
Comment faire ? J'ai un peu l'impression de faire du bricolage alors que les relations entre les 2 tables restent très connes !!
 
Help !!  :D


Message édité par spark le 03-02-2015 à 14:39:58

---------------
Un cycle complet sera une série de 100.
Reply

Marsh Posté le 03-02-2015 à 14:27:59   

Reply

Marsh Posté le 03-02-2015 à 14:36:48    

et le $this->B->find('all') me retourne de la merde...


---------------
Un cycle complet sera une série de 100.
Reply

Marsh Posté le 03-02-2015 à 16:55:14    

Pour B, utiliser hasMany plutôt que belongsTo, ça n'aiderait pas ?
 
(Je suis pas un spécialiste, c'est juste une piste de réflexion)


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 03-02-2015 à 17:09:51    

j'essaie ca demain, là c'est l'heure de partir du boulot, merci pour ton aide :)


---------------
Un cycle complet sera une série de 100.
Reply

Marsh Posté le 03-02-2015 à 17:30:49    

Essaie en augmentant le niveau de récursivité de ta requête


---------------
collectionneur de pâtes thermiques
Reply

Marsh Posté le 04-02-2015 à 15:09:09    

La récursivité ne change rien :sweat:  
 
Ca continue là : http://forum.cakephp-fr.org/viewto [...] 803#p33803


---------------
Un cycle complet sera une série de 100.
Reply

Marsh Posté le 05-02-2015 à 15:22:58    

'Solution' trouvée, enfin plutôt quelque chose qui fonctionne... (voir lien), si un pro du cake pouvait valider que c'est la bonne :D ou me jeter des cailloux :o  
Merci :jap:


---------------
Un cycle complet sera une série de 100.
Reply

Marsh Posté le 05-02-2015 à 15:32:10    

C'est donc ce que je disais non !?

kao98 a écrit :

Pour B, utiliser hasMany plutôt que belongsTo, ça n'aiderait pas ?


 
 :whistle:  


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 08-02-2015 à 20:31:54    

Heu oui :lol: Mais je trouve ma solution très sale pour deux simples relations de 2 clés étrangères... je trouve ca pas très "propre"...


---------------
Un cycle complet sera une série de 100.
Reply

Marsh Posté le 08-02-2015 à 22:43:37    

spark a écrit :

Heu oui :lol: Mais je trouve ma solution très sale pour deux simples relations de 2 clés étrangères... je trouve ca pas très "propre"...


Et pourquoi tu trouve ça pas très propre ?
Tu aurais voulu faire comment ?  :heink:  
 


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 08-02-2015 à 22:43:37   

Reply

Marsh Posté le 09-02-2015 à 13:44:23    

kao98 a écrit :


Et pourquoi tu trouve ça pas très propre ?
Tu aurais voulu faire comment ?  :heink:  
 


A.php:
 

Code :
  1. class A extends AppModel {
  2.     public $name = 'A';
  3.                        
  4.     public $hasOne= array(
  5.                 'Batch' => array(
  6.                                 'className' => 'B',
  7.                                 'foreignKey' => false,
  8.                                 'conditions' => array('Batch.id = A.b1_id')
  9.                                 ),
  10.                 'TP' => array(
  11.                                 'className' => 'B',
  12.                                 'foreignKey' => false,
  13.                                 'conditions' => array('TP.id = A.b2_id')
  14.                          )
  15.                 );
  16.   }
  17. ?>


B.php:
 

Code :
  1. class B extends AppModel {
  2.   public $name = 'B';
  3.  
  4.   public $order = array('B.name' => 'ASC');
  5.                          
  6.   public $hasMany  = array('A'=> array(
  7.                          'foreignKey' => false,
  8.                          'conditions' => array('OR' => array('A.b1_id' => '{$__cakeID__$}',
  9.                                                              'A.b2_id' => '{$__cakeID__$}') )
  10.                                       )
  11.                           );
  12. }


 
C'est le résultat que j'ai actuellement. Bon ça me retourne bien ce que je veux niveau données, mais je trouve que mon B.php, c'est du gros bidouillage.
 
Pour moi ce n'est pas une vraie relation. Je voyais plutôt 2 belongsTo correspondant à mes 2 hasOne, histoire que l'ORM sache faire les jointures tout seul comme un grand, là je trouve ça excessivement compliqué juste pour deux relations 1-n sur la même table...


Message édité par spark le 09-02-2015 à 13:45:50

---------------
Un cycle complet sera une série de 100.
Reply

Marsh Posté le 09-02-2015 à 14:18:20    

Et du coup, tu n'as pas l'impression que c'est ton modèle qui est foireux en cause ? :whistle:

 

La condition de ta relation hasMany de ton entité B reflète exactement ton modèle.

 

Ton modèle n'est pas normalisé. Ne soit pas surpris que ton ORM ne soit pas adapté !

 

Edit : le modèle n'est pas forcément foireux. Je ne connais pas ton projet, je ne peux pas me prononcer à ce sujet. Mais il n'est pas normalisé, ce qui n'est pas forcément pas correct. C'est juste pas normalisé.


Message édité par kao98 le 09-02-2015 à 14:25:38

---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 09-02-2015 à 15:04:11    

Ben c'est simple, ma table A, c'est des services, ma table B, c'est des serveurs.
Un service à 1 serveur de TP, et 1 serveur de Batch; d'où ma modélisation :

Code :
  1. service(id, name, tp_serveur_id, batch_serveur_id)


et  

Code :
  1. serveur(id, name)


avec  

Code :
  1. service.tp_serveur_id => serveur.id et
  2. service.batch_serveur_id => serveur.id


 
Je pense que c'est bien modélisé ou alors faut qu'on m'explique :kaola:  
Après, je peux passer par une autre table et faire du ternaire, mais vu que j'ai que 2 serveurs par service, c'est pas la peine... Et dans ma table serveurs, j'ai pas que du TP ou du Batch, j'ai de la BDD et autres...
 
Et pis même, un hasOne devrait avoir un belongsTo, enfin dans la doc c'est marqué comme ça :o


---------------
Un cycle complet sera une série de 100.
Reply

Marsh Posté le 09-02-2015 à 15:50:49    

spark a écrit :

Ben c'est simple, ma table A, c'est des services, ma table B, c'est des serveurs.
Un service à 1 serveur de TP, et 1 serveur de Batch; d'où ma modélisation :

Code :
  1. service(id, name, tp_serveur_id, batch_serveur_id)


et  

Code :
  1. serveur(id, name)


avec  

Code :
  1. service.tp_serveur_id => serveur.id et
  2. service.batch_serveur_id => serveur.id


 
Je pense que c'est bien modélisé ou alors faut qu'on m'explique :kaola:  
Après, je peux passer par une autre table et faire du ternaire, mais vu que j'ai que 2 serveurs par service, c'est pas la peine... Et dans ma table serveurs, j'ai pas que du TP ou du Batch, j'ai de la BDD et autres...
 
Et pis même, un hasOne devrait avoir un belongsTo, enfin dans la doc c'est marqué comme ça :o


 
Dans une version normalisée, il y aurait bel et bien 3 tables.
Service, Server, et ServiceHasServer(ServiceId, ServeurId, type).
 
BelongsTo, c'est pour une relation 1 => n, du côté du n. hasMany, c'est pour du côté du 1.
 
Exemle, si dans ton exemple, on avait eu 1 service pour n serveurs, mais un serveur pour 1 service. 1 service hasMany servers, 1 server belongsTo un service. La relation hasMany permet de retrouver l'ensemble des serveurs d'un service. BelongsTo permet de retrouver le service auquel appartient un serveur.
 
Dans cakePhp, la relation hasOne est plutôt dédiée aux relations 1 => 1.
 
Mais tu ne rentres pas dans ces cas là puisque tu as une relation 2 => n, que tu as dé-normalisé (donc un cas spécifique).


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 09-02-2015 à 15:59:19    

merci pour tes éclaircissements :jap: , je dormirai moins bête ce soir :)


---------------
Un cycle complet sera une série de 100.
Reply

Marsh Posté le 09-02-2015 à 16:03:53    

Je précise, si jamais c'est pas assez clair : ce n'est pas une mauvaise chose d'avoir dé-normalisé ! C'est une optimisation qui peut se justifier (ou pas) au sein de ton soft.
 
Si tu es sûr que tu n'auras toujours que 2 serveurs max par services, jamais un service n'en aura un 3ème, alors ton modèle se justifie :jap:


---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Marsh Posté le 10-02-2015 à 14:10:03    

LE truc aussi, c'est que un serveur peut héberger soit du TP, soit du Batch, soit de la BDD, soit 1, 2 ou 3 de ces éléments, donc je ne peux pas avoir une table type_serveur, car il peut avoir plusieurs fonctions.
Genre dans mon appli, pour les batchs, c'est la meme machine pour tous les services d'une appli précise, mais ce n'est pas le cas pour une autre appli. :pt1cable: :o


---------------
Un cycle complet sera une série de 100.
Reply

Marsh Posté le 10-02-2015 à 14:16:22    


Service n <=> n Server
          ||
          \/
           n
          Job


Modèliser en 4 tables : service, server, job, et ServiceHasServer(ServiceId, ServerId, JobId, Details[text])
C'est compliqué, mais au moins ça devrait pouvoir couvrir tous tes cas de figure. Et tu peux même avoir du blabla dans ton champ "details". Et ça te permet de sortir des listings dans tous les sens.

 

Un service peut avoir plusieurs serveurs, pour différents travaux
Un serveur peut être utilisé par plusieurs services, pour différents travaux
Tu peux même avoir un service qui utilise un serveur pour un job particulier, et le même serveur pour un autre type de job.

 

Bref, ça demande un petit "effort" de développement, mais une fois que c'est fait, tu es sûr de pouvoir tout faire avec un modèle de ce type sans être bloqué.


Message édité par kao98 le 10-02-2015 à 14:17:00

---------------
Kao ..98 - Uplay (R6S) : kao98.7.62x39 - Origin (BF4, BF1) : kntkao98
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed