Ordre de LaravelPar une relation

116

Je boucle sur tous les commentaires postés par l'auteur d'un article particulier.

foreach($post->user->comments as $comment)
    {
        echo "<li>" . $comment->title . " (" . $comment->post->id . ")</li>";
    }

Cela me donne

I love this post (3)
This is a comment (5)
This is the second Comment (3)

Comment puis-je commander par post_id pour que la liste ci-dessus soit classée 3,3,5

PrestonDocks
la source

Réponses:

247

Il est possible d'étendre la relation avec des fonctions de requête:

<?php
public function comments()
{
    return $this->hasMany('Comment')->orderBy('column');
}

[modifier après un commentaire]

<?php
class User
{
    public function comments()
    {
        return $this->hasMany('Comment');
    }
}

class Controller
{
    public function index()
    {
        $column = Input::get('orderBy', 'defaultColumn');
        $comments = User::find(1)->comments()->orderBy($column)->get();

        // use $comments in the template
    }
}

modèle utilisateur par défaut + exemple de contrôleur simple; lors de l'obtention de la liste des commentaires, appliquez simplement la commande orderBy () basée sur Input :: get (). (assurez-vous de faire quelques vérifications d'entrée;))

Rob Gordijn
la source
2
Quelqu'un l'a déjà suggéré sur le forum Laravel, mais je veux pouvoir le faire dans le contrôleur afin que je puisse choisir le champ à trier en fonction de l'entrée de l'utilisateur. Peut-être aurais-je dû préciser cela dans la question.
PrestonDocks
J'ai ajouté un deuxième exemple
Rob Gordijn
1
Merci Rob, vous m'avez mis sur la bonne voie. La réponse réelle était $ comments = User :: find (10) -> comments () -> orderBy ('post_id') -> get (); Il semblait avoir besoin de la méthode get () pour fonctionner. Si vous pouvez ajouter get () à votre réponse, je la marquerai comme réponse acceptée.
PrestonDocks
2
Cela fonctionne bien si vous récupérez un seul enregistrement, mais si vous récupérez plusieurs enregistrements, vous voudrez quelque chose de plus comme stackoverflow.com/a/26130907/1494454
dangel
Si vous utilisez le mode strict de mysql, qui est par défaut dans Laravel 5.4, par exemple, vous recevrez SQLSTATE [42000]: Erreur de syntaxe ou violation d'accès: 1140 Mélange de colonnes GROUP ...
Sabine
8

Je pense que vous pouvez également faire:

$sortDirection = 'desc';

$user->with(['comments' => function ($query) use ($sortDirection) {
    $query->orderBy('column', $sortDirection);
}]);

Cela vous permet d'exécuter une logique arbitraire sur chaque enregistrement de commentaire associé. Vous pourriez avoir des trucs là-dedans comme:

$query->where('timestamp', '<', $someTime)->orderBy('timestamp', $sortDirection);
agm1984
la source
1
Nan. J'ai essayé ça, ça ne marche pas. Voici mon cas: j'ai deux tables ( appointmentset schedules), la requête est simple: obtenir l' appointmentsordre par schedules. datetimedescendant. J'ai une solution en ajoutant une nouvelle colonne dans la table appointmentsà stocker à datetimepartir de la table schedules. Et maintenant, je n'ai plus qu'à passer commande appointments. datetimeJe sais que ce n'est pas la meilleure méthode, mais cela résout le problème. XD
Fendi Setiawan
Merci beaucoup, cela a fonctionné dans mon cas, c'était incroyable.
Pooria Honarmand