Relacje, wiele zapytań do bazy

0

Cześć, mam do Was pytanie związane z Laravel i relacjami, załóżmy że mam na stronie zakładkę Drużyny (którą tworzą ludzie), w niej oczywiście jest lista członków, czyli: Drużyna -> lista członków, no i teraz konkretnie muszę ich wyświetlić oraz ich status (a ich status jest określany przez obecność user_id w tabeli online_users [id, user_id]), moje rozwiązanie to relacja User -> OnlineUsers jednak to generuje na 30 członków w drużynie aż 30 zapytań! Jakieś pomysły jak zredukować ich ilość do minimum?

3

Pokaż modele i relacje jakie masz utworzone. Jak wywołujesz zapytanie ?
Jeśli zrobisz coś w stylu:

$data = Teams::where('id','=',$id)
            ->with('users')
            ->with('onlineUsers')
            ->get();

Powinien zadziałać Eager Loading i powinieneś mieć zredukowane zapytania do 3.
Zobacz w dokumentacji:
https://laravel.com/docs/8.x/[...]t-relationships#eager-loading

0

A po co dodatkowo tabela, by trzymać userów, co są online? Trochę przeinżynierowane to. Starczy trzymać w tabeli users datę ostatniego wejścia usera na stronę. I potem porównać z aktualną.

0
jurek1980 napisał(a):

Pokaż modele i relacje jakie masz utworzone. Jak wywołujesz zapytanie ?
Jeśli zrobisz coś w stylu:

$data = Teams::where('id','=',$id)
            ->with('users')
            ->with('onlineUsers')
            ->get();

Powinien zadziałać Eager Loading i powinieneś mieć zredukowane zapytania do 3.
Zobacz w dokumentacji:
https://laravel.com/docs/8.x/[...]t-relationships#eager-loading

Sprawdzę Twoje rozwiązanie i dam znać (obecnie jestem na etapie przepisywania strony więc chwile to zajmie, po prostu pamiętam, że miałem tutaj z tym problem).

serek napisał(a):

A po co dodatkowo tabela, by trzymać userów, co są online? Trochę przeinżynierowane to. Starczy trzymać w tabeli users datę ostatniego wejścia usera na stronę. I potem porównać z aktualną.

Strona / baza danych jest połączona z aplikacją, która w ten sposób zapisuje obecnie aktywnych użytkowników.

0

Ok, napotkałem przeszkodę w innej sytuacji, może ktoś byłby w stanie mi pomóc, mam klase Guild, ona relacje do GuildRank a z niej idzie relacja do GuildMembership (wszędzie hasMany) no i wszystko działa poprawnie:

title

jednak gdy dodałem eager loading w klasie gdzie wczytuje Guild

title

zapytanie zmienia guild_id w NULL
title

dokładniej w tej części guild_id zmienia się w NULL

return $this->hasMany(GuildMembership::class, 'rank_id')->where('guild_id', $this->guild_id);

jakieś pomysły dlaczego?

0

Trochę dziwne to rozwiązanie.
Dlaczego używasz czegoś takiego:

return $this->hasMany(GuildMembership::class, 'rank_id')->where('guild_id', $this->guild_id);

Piszę teraz z pamięci ale chyba pierwsze hasMany zwróci instancję relacji i wywołanie na czymś takim where pewnie zwróci null.
To jest część Twojej relacji czy jakiegoś zapytania?

Pokaż dokładnie gdzie używasz tego eagerloadingu. To with przy view to załączenie zmiennej do widoku.

0

W ten sposób pobieram liste członków drużyny, guild_ranks to ich kategorie (np. menadżer, vice-menadżer, zwykły użytkownik), guild_membership to lista członków (user_id, rank_id ( czyli kategoria )) i stąd będę w stanie przejść do ostatniego modelu czyli klasy Player (po user_id)

Widok:

@foreach($guild->ranks as $rank)
    @foreach($rank->members as $member)
        <tr>
            <td>{{ $rank->getName() }}</td>
            <td>-- tutaj byloby {{ $member->player->COS }} itd</td>
            <td>2</td>
        </tr>
    @endforeach
@endforeach

Kontroler:

public function index(Guild $guild)
{
    $guild->load('ranks.members');
    return view('community.guilds.show')->with(compact('guild'));
}

Model Guild:

public function ranks() {
    return $this->hasMany(GuildRank::class, 'guild_id', 'id');
}

Model GuildRank:

public function members() {
    return $this->hasMany(GuildMembership::class, 'rank_id')->where('guild_id', $this->guild_id);
}

Czyli wszystkie się sypie (wstawia mi null zamiast guild_id) w momencie dodania

$guild->load('ranks.members');

do kontrolera :x chcę po prostu zredukować ilość zapytań przykładowo z 3 na 1 (zależnie od ilości kategorii)

1

Może się mylę ale powtórzę, to nie wygląda na poprawną relację:

public function members() {
    return $this->hasMany(GuildMembership::class, 'rank_id')->where('guild_id', $this->guild_id);
}

Filtruj z użyciem where na wynikach zapytania.

0

Rzeczywiście, chyba masz racje, dzięki!

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0