Bonjour, je rencontre des difficultés à effectuer un ajout d'attribut dans un résultat de requête :
$users = $this->Users->find('All');
$users
contient la liste des utilisateurs et leurs attributs respectifs en base de données, j'aimerais ajouter un champ distance
qui est complètement dynamique en fonction de leurs positions à l'instant de la demande.
UsersController :
foreach ($users as $key => $user) {
$user->distance = getDist($lat, $lng);
// A ce stade j'ai bien ajouté 'distance' à mon objet users, enfin je présume je le retrouve bien dans le debug() du controller users (la fonction `getDist()` elle, me retourne un `float`)
}
Cependant dans mon foreach
qui est dans la vue, $user->distance
est inexistant.
Y a-t-il un moyen d'ajouter des données à la volé dans un objet de requête comme une Propriétés Virtuelles dynamique ?
Ensuite dans le cas ou le champ $user->distance
est fonctionnel, je veux trier l'objet pour que le premier index soit la plus petite distance. Voici théoriquement comment je procèderai :
usort($users, function($a, $b){
if ($a->distance === $b->distance) {
return 0;
}
if ($a->distance < $b->distance) {
return -1;
}
return 1;
});
Puis j'envoi à la vue :
$this->set('users', $this->paginate($users));
Merci, j'attend vos remarques avec impatience.
Merci pour cette réponse parfaite concernant la première partie avec les Champs Calculés, par contre comme vous l'aviez prédit le tri sur le champ distance n'est pas reconnu, y a-t-il un moyen de l'effectuer ?
Suite à de nombreuses complications pour trier le champ distance qui n'existe pas en base, j'ai décidé de changer la logique :
J'ai crée un table distances
associé au utilisateurs qui contient le résultat de mon calcule et un uuid
qui me permet d'isoler les résultats.
Merci pour votre aide qui ma permis de réviser ma logic.
Hello,
Voilà pour la première partie :
$users = $this->Users
->find('all')
->formatResults(function ($users) use ($lat, $lng) {
return $users->map(function ($user) use ($lat, $lng) {
$user->distance = getDist($lat, $lng);
return $user;
});
});
Quand à la seconde, là je suis pas sûr de savoir comment faire. Essaye déjà avec ta méthode, si ça ne fonctionne pas, essaye avec un order comme ceci : (Mais c'est pas sûr qu'il reconnaisse le champ distance)
$users = $this->Users
->find('all')
->formatResults(function ($users) use ($lat, $lng) {
return $users->map(function ($user) use ($lat, $lng) {
$user->distance = getDist($lat, $lng);
return $user;
});
})
->order(
'distance' => 'ASC'
);