Laravel OrderBy na związku

116

Zapętlam wszystkie komentarze zamieszczone przez Autora danego wpisu.

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

To mi daje

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

Jak zamówić przez post_id, aby powyższa lista była uporządkowana jako 3,3,5

PrestonDocks
źródło

Odpowiedzi:

247

Możliwe jest rozszerzenie relacji o funkcje zapytań:

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

[edytuj po komentarzu]

<?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
    }
}

domyślny model użytkownika + prosty przykład kontrolera; podczas pobierania listy komentarzy, po prostu zastosuj polecenie orderBy () w oparciu o Input :: get (). (pamiętaj, aby sprawdzić dane wejściowe;))

Rob Gordijn
źródło
2
Ktoś już zasugerował to na forum Laravel, ale chcę mieć możliwość zrobienia tego w kontrolerze, abym mógł wybrać, które pole sortować według danych wprowadzonych przez użytkownika. Być może powinienem był to wyjaśnić w tej kwestii.
PrestonDocks
Dodałem drugi przykład
Rob Gordijn
1
Dzięki Rob, postawiłeś mnie na właściwej drodze. Właściwa odpowiedź brzmiała $ comments = User :: find (10) -> comments () -> orderBy ('post_id') -> get (); Wydawało się, że do działania potrzebna jest metoda get (). Jeśli możesz dodać get () do swojej odpowiedzi, oznaczę ją jako zaakceptowaną odpowiedź.
PrestonDocks
2
Działa to dobrze, jeśli pobierasz pojedynczy rekord, ale jeśli
pobierasz
Jeśli używasz trybu ścisłego mysql, który jest domyślny w Laravel 5.4, f.ex, otrzymasz SQLSTATE [42000]: błąd składni lub naruszenie dostępu: 1140 Mieszanie kolumn GROUP ...
Sabine
8

Uważam, że możesz również:

$sortDirection = 'desc';

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

To pozwala na uruchomienie dowolnej logiki dla każdego powiązanego rekordu komentarza. Możesz tam mieć takie rzeczy jak:

$query->where('timestamp', '<', $someTime)->orderBy('timestamp', $sortDirection);
agm1984
źródło
1
Nie. Próbowałem tego, ale to nie działa. Oto mój przypadek: mam dwie tabele ( appointmentsi schedules), zapytanie jest proste: zdobądź appointmentszamówienie schedules. datetimemalejąco. Mam rozwiązanie, dodając nową kolumnę w tabeli appointmentsdo przechowywania datetimez tabeli schedules. A teraz wystarczy złożyć zamówienie appointments. datetimeWiem, że to nie jest najlepsza metoda, ale rozwiązuje problem. XD
Fendi Setiawan
Dziękuję bardzo, w moim przypadku zadziałało, było niesamowite.
Pooria Honarmand