EDIT : nouvelle requête, plus simple.

Bonjour,

Voici la requête fonctionnant dans phpMyAdmin :

SELECT SeanceUsers.id AS `SeanceUsers__id`,
SeanceUsers.user_id AS `SeanceUsers__user_id`,
SeanceUsers.content AS `SeanceUsers__content`,
SeanceUsers.level AS `SeanceUsers__level`, 
SeanceUsers.intensity AS `SeanceUsers__intensity`,
SeanceUsers.duration AS `SeanceUsers__duration`,
SeanceUsers.help AS `SeanceUsers__help`,
SeanceUsers.observation AS `SeanceUsers__observation`,
SeanceUsers.views_count AS `SeanceUsers__views_count`,
SeanceUsers.comments_count AS `SeanceUsers__comments_count`, 
SeanceUsers.created AS `SeanceUsers__created`,
SeanceUsers.modified AS `SeanceUsers__modified`, 
Users.id AS `Users__id`, 
Users.last_seance_id AS `Users__last_seance_id`, 
Users.username AS `Users__username`, 
Users.avatar AS `Users__avatar`, 
Users.slug AS `Users__slug`, 
Users.objectif AS `Users__objectif`, 
Users.weight AS `Users__weight`, 
Users.size AS `Users__size` 
FROM seance_users SeanceUsers 
LEFT JOIN users Users ON Users.id = (SeanceUsers.user_id) 
WHERE SeanceUsers.id = Users.last_seance_id 
ORDER BY SeanceUsers.created desc

Le but étant d'afficher seulement la dernière séance de chaque membre. Car un membre peut avoir plusieurs séances, mais à l'affichage sur l'index, j'aimerai lister que la séance la plus récente de chaque membre.

J'enregistre donc la dernière séance (last_seance_id) dans la table user.

Malheureusement, je n'arrive pas utiliser un champs se trouvant dans un contain. Pour l'instant, je n'ai que ceci :

// SeanceController.php
$this->loadModel('SeanceUsers');
$seances = $this->SeanceUsers
            ->find()
            //->autoFields(true)
            ->contain([
                'Users' => function ($q) {
                    return $q->select(['id' ,'last_seance_id', 'username', 'avatar', 'slug', 'objectif', 'weight', 'size']);
                }
            ])
            ->where([
                'SeanceUsers.id' => 'Users.last_seance_id'
            ])
            ->order([
                'SeanceUsers.created' => 'desc'
            ]);

Ce qui me donne en SQL :c0 à la place de Users.last_seance_id, il ne prend pas en compte mon champs:

'params' => [
        ':c0' => [
            'value' => 'Users.last_seance_id',
            'type' => 'integer',
            'placeholder' => 'c0'
        ]
    ]

Donc comment utiliser un champs se trouvant dans un contain (dans user, je veux last_seance id) pour le comparer par la suite avec l'id de la séance ?

Merci d'avance.

4 réponses


JeremyB
Auteur
Réponse acceptée

Bonjour,

J'ai résolu mon problème en faisant autrement : dans ma table seance_users, j'ai rajouté un champs is_last prenant comme valeur 0 ou 1. Ainsi, lorsque je rajoute une séance, je mets la nouvelle séance à 1 et l'ancienne à 0, et à l'index, je fais une requête en prenant en compte is_last = 1 dans le where.

Beaucoup plus simple, moins prise de tête. Merci quand même.

JeremyB
Auteur

Petit Up s'il vous plait. J'ai éditer complètement mon message ci-dessus car j'ai revu toute ma requête SQL.

Premiere question dans le model tu as bien l'association ?
2° que donne le result avec juste ->contain(['Users'])

JeremyB
Auteur

Dans SeancesController.php :

$this->loadModel('SeanceUsers');
        $this->paginate = [
            'maxLimit' => Configure::read('Seance.seance_per_page')
        ];

        $seances = $this->SeanceUsers
            ->find()
            ->contain([
                'Users' => function ($q) {
                    return $q->select(['id' ,'last_seance_id', 'username', 'avatar', 'slug', 'objectif', 'weight', 'size']);
                }
            ])
            ->where([
                'SeanceUsers.id' => 'Users.last_seance_id'
            ])
            ->order([
                'SeanceUsers.created' => 'desc'
            ]);

        $seances = $this->paginate($seances);

        $this->set(compact('seances'));

Dans SeanceUsersTable.php :

$this->belongsTo('Users', [
            'foreignKey' => 'user_id'
        ]);

Dans UsersTable.php :

$this->hasMany('SeanceUsers', [
            'foreignKey'       => 'user_id',
            'dependent'        => true,
            'cascadeCallbacks' => true
        ]);

Avec une requête simple comme ceci :

$this->loadModel('SeanceUsers');
        $this->paginate = [
            'maxLimit' => Configure::read('Seance.seance_per_page')
        ];

        $seances = $this->SeanceUsers
            ->find()
            ->contain([
                'Users' => function ($q) {
                    return $q->select(['id', 'username', 'avatar', 'slug', 'objectif', 'weight', 'size']);
                }
            ])
            ->order([
                'SeanceUsers.created' => 'desc'
            ]);

        $seances = $this->paginate($seances);

        $this->set(compact('seances'));

Ça me donne ceci dans la table seance_users :

  id   |  user_id   |   created   
-------|------------|------------ 
   3   |     2      |  18/01/15
   2   |     2      |  17/01/15
   1   |     1      |  16/01/15

Mais avec ce code là (en groupant par rapport à user_id) :

$this->loadModel('SeanceUsers');
        $this->paginate = [
            'maxLimit' => Configure::read('Seance.seance_per_page')
        ];

        $seances = $this->SeanceUsers
            ->find()
            ->contain([
                'Users' => function ($q) {
                    return $q->select(['id', 'username', 'avatar', 'slug', 'objectif', 'weight', 'size']);
                }
            ])
            ->group([
                'SeanceUsers.user_id'
            ])
            ->order([
                'SeanceUsers.created' => 'desc'
            ]);

        $seances = $this->paginate($seances);

        $this->set(compact('seances'));

J'aurai voulu avoir :

  id   |  user_id   |   created   
-------|------------|------------ 
   3   |     2      |  18/01/15
   1   |     1      |  16/01/15

(résultat obtenu avec ma requête SQL dans mon premier message)

Mais ça me donne ça :

  id   |  user_id   |   created   
-------|------------|------------ 
   2   |     2      |  17/01/15
   1   |     1      |  16/01/15

En gros, le group sur user_id me prend le plus petit id de la séance (soit la première séance du membre) alors que j'aimerai qu'il me donne le dernier id de la séance du membre ! une sorte de group by sur user_id mais desc sur l'id de la séance.

Je dois buguer quelque part, et pourtant ça ne doit pas être compliqué à récupérer ce genre d'info (comme récupérer le dernier article pour chaque catégorie, récupérer le dernier sujet de chaque forum etc).