Laravel - relacje a sortowanie

Laravel - relacje a sortowanie
ST
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Cześć, podczas pisania strony napotkałem pewien problem, czy jest możliwość sortowania w relacjach?

Powiedzmy mam tabele UsersOnline z relacją hasOne do Users, pobieram wszystkich użytkowników online w ten sposób:
$list = UsersOnline::with('user')->get();

no i chciałbym to posortować po wartościach z Users czyli tej relacji, innym rozwiązaniem może byłoby zmienić te zapytanie na RAW? z left join itd ale wtedy nie miałbym możliwości z korzystania funkcji modelu (np. user->getSlug() etc)

jurek1980
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3581
2

Możesz użyć notacji kropkowej z Laravel i zrobić coś takiego:

Kopiuj
$list = UsersOnline::with('user')
    ->orderBy('user.id')
    ->get();
ST
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

@jurek1980: niestety ale wyrzuca takie zapytanie select * from `users_online` order by `users`.`online_time` asc, udało mi się uzyskać efekt stosując coś takiego:

Kopiuj
$list = $list->sortByDesc(function($row) use ($sortKey) {
    return $row->user->$sortKey;
})

co myślisz?

Edit: tylko mam problem z sortowaniem alfabetycznym a-z, nie działa, jedynie na liczby..

jurek1980
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3581
0

Ale ten online_time to w tabeli users_online tak? No bo tak po co Ci odrębny model?
Pokaż jak byś to zapisał w SQL i jakie masz kolumny w tabeli.

ST
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Tak, ten online_time (nazwa kolumny tylko przykładowa) znajduje się w tabeli Users czyli tej do której UsersOnline ma relacje i po tym właśnie chce sortować.
W SQL zrobiłbym to na zasadzie

Kopiuj
SELECT * FROM `users_online` `uo` LEFT JOIN `users` `u` ON `u`.`id` = `uo`.`user_id` ORDER BY `u`.`online_time` DESC

Edit. ewentualnei zerknij post wyżej, edytowałem post z nowym sortowaniem

mr_jaro
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Grudziądz/Bydgoszcz
  • Postów: 5300
0

Jedyną rozsądną opcją jest sortowanie na kolekcji którą dostaniesz po wywołaniu get(), Twój pomysł, który podałeś jest strasznie niewydajny.
Drugą opcją jest zamiana kolejności i zrobienie Users::whereHas(...)->...

ST
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

@mr_jaro: czyli to nie wykonuje się na kolekcji?

Kopiuj
UsersOnline::with('user')->get()->sortByDesc(function($row) use ($sortKey) {
     return $row->user->$sortKey;
});
mr_jaro
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Grudziądz/Bydgoszcz
  • Postów: 5300
1

@storm.: to tak, nie pokazałeś całego kodu wyglądało jak wersja sprzed geta. więc to co pokazujesz teraz jest ok.

ST
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

@mr_jaro: a wiesz może jak zrobić te sortowanie aby działało również na litery? przykładowo jeśli chciałbym posortować ludzi po imieniu, bo obecnie działa jedynie na liczby

mr_jaro
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Grudziądz/Bydgoszcz
  • Postów: 5300
2
Kopiuj
UsersOnline::with('user')->get()->sort(function ($a, $b) {
                return $a->user->name > $b->user->name;
            });
ST
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 45
0

Dzięki!

OM
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 162
0

Relacja powinna być raczej belongsTo, a nie hasOne w tym przypadku.
Możesz sobie zrobić leftJoina jednej i drugiej tabeli i posortować od razu w zapytaniu, według dowolnej kolumny.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.