• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[Laravel Eloquent] Lista użytkowników z dostępem do kategorii

0 głosów
544 wizyt
pytanie zadane 29 sierpnia 2020 w PHP przez niezalogowany

Mam tabele i modele:

users: [id, email, itd bez znaczenia]

categories: [id, name]

access_categories [id, user_id, category_id]

Potrzebuje z tego pobrać maile użytkowników.z dostępem do danej kategorii. Mam taki kod który działa ale wydaje mi się że dało by się to zrobić lepiej.

    public static function withAccessToCategory($categoryId)
    {
        $usersWithAccessToCategory = AccessCategories::where('category_id', $categoryId)->get(['user_id'])->toArray();
        $emails = [];
        foreach ($usersWithAccessToCategory as $userId) {
            $emails[] = User::find($userId)->first()->getEmail();
        }

        return $emails;
    }

 

1 odpowiedź

0 głosów
odpowiedź 2 września 2020 przez Bizuma Gaduła (3,650 p.)

No to tak, pierwsza rzecz jaka rzuca się w oczy to User::find(); Problem polega na tym, że w celu pobrania adresu email dla każdego usera wykonujesz za każdym razem nowe zapytanie do bazy danych. Przy większej ilości użytkowników może to być problem.

Skoro posiadasz już tablicę z ID wszystkich potrzebnych ci użytkowników to możesz zastąpić pętlę używając metody "whereIn" aby pobrać wszystkich tych userów na raz:

$users = User::whereIn('id',  $usersWithAccessToCategory)->get();

Następnie jeżeli potrzebujesz tablicy z samymi adresami email możesz ją utworzyć w taki sposób:

$emails = $users->pluck('email')->toArray();

Dzięki temu zmniejszysz ilość zapytań do bazy danych z $usersWithAccessToCategory + 1 do dwóch.

 

No ale to póki co takie porady na przyszłość.

Można to zrobić jeszcze lepiej, bo tylko jednym zapytaniem do bazy.

Definicja relacji w modelu Usera:

    public function categories(){
        return $this->belongsToMany(Category::class, 'access_categories', 'user_id', 'category_id');
    }

Samo wyciągnięcie adresów:

        $exampleCategoryId = 3;
        $emails = User::select(['email'])->whereHas('categories', function(Builder $query) use ($exampleCategoryId){
            $query->where('categories.id', $exampleCategoryId);
        })->get()->toArray();

Swoją drogą jeżeli masz wątpliwości to polecam metodę "enableQueryLog()" w celu sprawdzenia ile/jakie zapytania są wykonywane do bazy danych i czy nie da się tego ulepszyć.

        DB::enableQueryLog();

        // tutaj jakieś operacje na bazie danych

        $executedQueries = DB::getQueryLog();
        dd($executedQueries);

 

komentarz 2 września 2020 przez niezalogowany

Dzięki za odpowiedź. Trochę to zagmatwałem i mogłrm wywoływać to na kategorii.

    public function usersEmails()
    {
        return $this->belongsToMany(User::class, 'access_categories')->get()->pluck('email')->toArray();
    }

 

Podobne pytania

0 głosów
0 odpowiedzi 241 wizyt
0 głosów
1 odpowiedź 336 wizyt
pytanie zadane 8 marca 2021 w PHP przez niezalogowany
0 głosów
3 odpowiedzi 569 wizyt

93,604 zapytań

142,527 odpowiedzi

322,995 komentarzy

63,090 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Kursy INF.02 i INF.03
...