Bonjour à tous,

Voici mon cas, j'ai quatre tables :

clients--1,1----0,n-->villes--1,1----0,n--> département--1,1----0,n-->regions

j'aimerai faire un find('first) pour trouver un client quelconque dans une région et aussi avec quelques conditions sur le client genre (si ça fiche est traité ou pas ) , j'ai essayé avec le comportement containable mais j'ai pas pu mettre la condition de la région:

$client=$this->find('first',array(
            'conditions'=>array('Client.id'=>$client_id),
            'contain'=>array(
                'Specialite',
                'Category',
                'Ville'=>array(
                    'Departement'=>array(
                        'Region'
                        )
                    )
                ),
            ));

et quand je met la condition dans la région :

$client=$this->find('first',array(
            'conditions'=>array('Client.id'=>$client_id),
            'contain'=>array(
                'Specialite',
                'Category',
                'Ville'=>array(
                    'Departement'=>array(
                        'Region'=>array(
                                                        'conditions'=>array('id'=>1),
                                                            )
                        )
                    )
                ),
            ));

il me trouve un client mais qui n'est pas de cette région et le résultat de la région est un tableau vide.

du coup j'ai construit une requête joins comme suit:

$client=$this->find('first',array(
            'joins'=>array(
                array('table' => 'villes',
                    'alias' => 'Ville',
                    'type' => 'LEFT',
                    'conditions' => array(
                        'Ville.id = Client.ville_id',
                    )
                ),
                array('table' => 'departements',
                    'alias' => 'Departement',
                    'type' => 'LEFT',
                    'conditions' => array(
                        'Departement.id = Ville.departement_id',
                    )
                ),
                   array('table' => 'regions',
                    'alias' => 'Region',
                    'type' => 'LEFT',
                    'conditions' => array(
                        'Region.id = Departement.region_id',
                    )
                )
            ),
                 'conditions'=>array(
                    'Region.id'=>$region_id,
                    'Client.processed'=>false,
                    )
            ));

la j'ai le résultat que je recherche mais j'ai pas les infos sur la ville et département et région sauf les infos de la table client, alors du coup je récupère le 'id' de ce client et je refait un find('first') avec le comportement containable pour tous bien récupérer.

Ma question:
-Peut on faire une recherche avec le comportement containable d'une grande profondeur comme dans mon exemple et avec des conditions dans la dernière table.
-Sinon si il y'a une autre astuce pour mon cas de tel sorte qu'une requête est suffisante

2 réponses


Bonjour,
voilà le gros problème de cakePHP...
Le containable est vraiment pas très efficace...
Contrairement à un left join au bout du deuxième niveau il va faire des sous-requêtes... Donc impossible de faire des tri ou des conditions dessus. Analyse bien les requêtes sql qu'il te génère et tu veras.
Sinon j'ai eu exactement le même problème que toi et après quelque jours de recherche (avec surtout des gens qui disaient que cakephp c'est pas top...) j'ai choisis de contourner le problème et de créer une vue de toute mes tables.
Ma vue inclue tout mes left join et du coup je peux trier et faire ce que je veux dessus.

Voilà le topics où j'ai posté : http://www.grafikart.fr/forum/topic/8200

Créer des vues en mysql : http://dev.mysql.com/doc/refman/5.0/fr/create-view.html

Cordialement

cmoualis
Auteur

Merci Nightbringer, j'ai aussi remarqué que Containable ne va pas plus de deux profondeurs et pour ça j'ai gardé pour l'instant ma méthode qui est de faire la requête comme celle que j'ai déclaré au début et après avoir récupéré l'id du client je fait un find first avec conditions sur l'id et bien sur en utilisant le containable pour tous récupéré sur les quatre profondeurs. voila pour l'instant c'est la seule solution que j'ai trouvé.

Cordialement.