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.
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.
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'])
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).