Bonjour à tous!
Depuis très peu sous cakephp :)
Voilà mon soucis pour créer une liste déroulante des régions et des départements.
Lorsque je fait la méthode bourrin comme le dit Graf dans son tuto http://www.grafikart.fr/formation/cakephp/associations-model
Ça marche mais fatale erreur trop long:
Dans DepartmentController sans rien dans mon modèle

public function index(){
        $departments = $this->Department->find('all', array(
            'fields' => array('Department.num', 'Department.name', 'Region.id', 'Region.name'),
            'joins' => array(
                array(
                    'table' => 'regions',
                    'alias' => 'Region',
                    'type' => 'LEFT',
                    'conditions' => array('Region.id = Department.region_id')
                )
            )
        ));
            debug($departments);
        $this->set(compact('departments'));
    }

Renvoit

array(
    (int) 0 => array(
        'Department' => array(
            'num' => '01',
            'name' => 'Ain'
        ),
        'Region' => array(
            'id' => '22',
            'name' => 'Rhône-Alpes'
        )
    ),

etc.
Résultat de la requête:

SELECT `Department`.`num`, `Department`.`name`, `Region`.`id`, `Region`.`name` FROM `gooddeal`.`departments` AS `Department` LEFT JOIN `joe`.`regions` AS `Region` ON (`Region`.`id` = `Department`.`region_id`) WHERE 1 = 1

Par contre si je laisse mon DepartmentsController.php comme dans le tuto:

public function index(){
        $departments = $this->Department->find('all');
            debug($departments);
        $this->set(compact('departments'));
    }

Mon modèle Department.php

public $belongsTo = array( 
        'Region' => array( 
            'classname' => 'Region', // nom de la classe = Region
            'foreignKey' => 'Region.region_id',
    'fields' => array('Region.id', 'Region.name', 'Region.slug'),
            'counterCache' => true
        )
    );

Ça ne me renvoie que les départements avec la clé region_id mais pas la région.

(int) 0 => array(
        'Department' => array(
            'id' => '1',
            'num' => '01',
            'name' => 'Ain',
            'slug' => 'ain',
            'region_id' => '22',
            'country' => 'fr'
        )
    ),
    (int) 1 => array(
        'Department' => array(
            'id' => '2',
            'num' => '02',
            'name' => 'Aisne',
            'slug' => 'aisne',
            'region_id' => '20',
            'country' => 'fr'
        )
    ),

et il ne me sélectionne effectivement pas ma région
Résultat de la requête:

SELECT `Department`.`id`, `Department`.`num`, `Department`.`name`, `Department`.`slug`, `Department`.`region_id`, `Department`.`country` FROM `joe`.`departments` AS `Department` WHERE 1 = 1

Par contre ce qui est marrant c'est que mon counterCache fonctionne. A ne rien y comprendre

Plusieurs fois que je regarde si je ne me suis pas trompé par rapport à la vidéo et au book de cake mais niet je ne vois absolument pas ou je bug. Au bout de deux jours, je finis par ne plus savoir comment faire.

Merci par avance de votre aide.

6 réponses


Airday
Réponse acceptée

Dans Region.php

public $hasMany = array(
    'Department' => array(
        'className' => 'Department',
        'foreignKey' => 'region_id'
        'order' => 'Department.num DESC'
    )
);

T'as oublie de préciser la cle etrangere.

Dans Department.php

public $belongsTo = array(
    'Region' => array(
        'classname' => 'Region', // nom de la classe = Region
        'foreignKey' => 'region_id',
        'fields' => array('Region.id', 'Region.name', 'Region.slug'),
        'counterCache' => true
    )
);
Lartak
Réponse acceptée

Bonjour.
Je te conseille d'utiliser le Behavior Containable, dans ton AppModel tu mets

public $recursive = -1;
public $actsAs = array('Containable');

Ensuite dans ton DepartmentController (je rappelle que les controller doivent être au pluriel, mais bon)

$departments = $this->Department->find('all', array(
        'fields' => array('Department.number', 'Department.name'),
        'contain' => array('Region' => array('fields' => array('name')))));
        $this->set(compact('departments'));

Si tes associations dans tes model sont bien faites, tu verras que ça fonctionne.

Tu dois creer un model Region qui a comme relation $hasMany vers Departement :)

mimosa21
Auteur

Merci Airday de m'accorder un peu de ton temps. J'avais déjà mon modèle Region.php. J'ai rajouté ces lignes

public $hasMany = array(
        'Department' => array(
            'className' => 'Department',
            'order' => 'Department.num DESC'
        )
    );

et j'obtiens toujours le même résultat

(int) 0 => array(
        'Department' => array(
            'id' => '1',
            'num' => '01',
            'name' => 'Ain',
            'slug' => 'ain',
            'region_id' => '22',
            'country' => 'fr'
        )
    ),
    (int) 1 => array(
        'Department' => array(
            'id' => '2',
            'num' => '02',
            'name' => 'Aisne',
            'slug' => 'aisne',
            'region_id' => '20',
            'country' => 'fr'
        )
    ),

Résultat de la requête toujours

SELECT `Department`.`id`, `Department`.`num`, `Department`.`name`, `Department`.`slug`, `Department`.`region_id`, `Department`.`country` FROM `joe`.`departments` AS `Department` WHERE 1 = 1

Et autant pour moi le counterCache fonctionnait avec la méthode bourrin, plus maintenant.

Merci en tout cas, je pense que rajouter la méthode $hasMany dans le modèle Region fait partie de la solution.
Toujours au même point!

mimosa21
Auteur

Toujours le même résultat.
Par contre une question que je me pose. En Parallèle de ma liste départements et région, je faisais le tuto sur l'inscription. Et avec wamp, je n'arrivais pas à configurer l'envoi de mes mails. J'ai planté wamp, je l'ai réinstallé et depuis je me demande si je n'ai pas désactivé une librairie ou supprimé qque chose d'important.
Si oui, ce pourrait être quoi?

mimosa21
Auteur

Grand merci à tous les deux,

Ça fonctionne :)

Lartak11: l'erreur venait bien du Behavior Containable, dans mon AppModel. Le DepartmentController etait une erreur de frappe dans ce post et j'ai mis aussi ton code dans mon DepartmentsController.

Merci beaucoup, une grosse prise de tête en moins.