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

Laravel - pobieranie danych z kilku tabel na podstawie relacji.

VPS Starter Arubacloud
+1 głos
662 wizyt
pytanie zadane 30 kwietnia 2018 w PHP przez User007 Bywalec (2,400 p.)

Witam. Chciałbym się dowiedzieć czy jest możliwość optymalizacji zapytania do bazy danych gdzie pobieram dane z 3 tabel z uwzględnieniem tabeli referencyjnej.

Mam tak

DB
table_users table_roles tableReference_roles_to_permissions table_permissions
id id role_id id
name name permission_id name
role_id      

W modelu User mam:

public function getRole()
    {
        return $this->belongsTo('App\Models\Role','role_id');
    }

W modelu Role mam:

public function getUsers()
    {
        return $this->belongsToMany('App\Model\User');
    }

    public function getPermissions(){

        return $this->belongsToMany('App\Models\Permission','roles_has_permissions','role_id','permission_id');
    }

I teraz co chcę uzyskać to pobrać użytkownika z przypisaną rolą i z przypisanymi "permissions" dla tej roli.

Obecnie mam to rozwiązane w ten sposób:

$user = User::with(['getRole:id,name'])->where(['id'=>1])->first();
$role = Role::find($user->role->id)->getPermissions;

        echo $user.' | '.$role;

Czy da się to połączyć wszystko w jednym zapytaniu "User::" ?

I drugie pytanie:

Czy w tym zapytaniu "Role::find($user->role->id)->getPermissions;", można dokonać sprawdzenia czy permission o danym name istnieje?

Czy po prostu muszę to w pętli sprawdzić?

Dziękuję.

1 odpowiedź

+2 głosów
odpowiedź 1 maja 2018 przez KlejnotNilu Użytkownik (750 p.)
wybrane 2 maja 2018 przez User007
 
Najlepsza

1. Czy da się to połączyć wszystko w jednym zapytaniu "User?

User::find($id)->with('role.permissions')->get();

Musisz mieć utworzone relacje Eloquentowe w modelach:
User.php

    public function role() {
        return $this->belongsTo(Role::class);
    }

Role.php

    public function users() {
        return $this->hasMany(User::class);
    }

    public function permissions() {
        return $this->belongsToMany(Permission::class);
    }

Permission.php

    public function roles() {
        return $this->belongsToMany(Role::class);
    }

Dodatkowo twórz relacje obustronne. Dla przykładu użytkownik posiada wiele postów, post ma tylko jednego użytkownika ( autora ). To w obu modelach powinieneś utworzyć odpowiednie metody.
User.php:

public function posts() {
    return $this->hasMany(Post::class);
}

Post.php:

public function user() {
    return $this->belongsTo(User::class);
}

A tu przykładowy wynik zapytania w JSONie ( już nie chciało mi się usuwać timestampów ;) ):
 

[  
   {  
      "id":1,
      "name":"Pawe\u0142",
      "email":"pawel@gmail.com",
      "role_id":1,
      "created_at":null,
      "updated_at":null,
      "role":{  
         "id":1,
         "role":"admin",
         "created_at":null,
         "updated_at":null,
         "permissions":[  
            {  
               "id":1,
               "name":"add",
               "created_at":null,
               "updated_at":null,
               "pivot":{  
                  "role_id":1,
                  "permission_id":1
               }
            },
            {  
               "id":2,
               "name":"delete",
               "created_at":null,
               "updated_at":null,
               "pivot":{  
                  "role_id":1,
                  "permission_id":2
               }
            },
            {  
               "id":3,
               "name":"edit",
               "created_at":null,
               "updated_at":null,
               "pivot":{  
                  "role_id":1,
                  "permission_id":3
               }
            }
         ]
      }
   }
]

2. Czy w tym zapytaniu "Role::find($user->role->id)->getPermissions;"można dokonać sprawdzenia czy permission o danym name istnieje?

Nie do końca rozumiem zamysł. Jedyne co mi teraz przychodzi do głowy i może trochę nakieruje to:

   Role::whereHas('permissions', function($query) {
      $query->where('name', 'add');
   })->get();

To zwróci kolekcję ról, która posiada uprawnienia do dodawania ( add ).

komentarz 1 maja 2018 przez User007 Bywalec (2,400 p.)

Dziękuję za wyczerpującą odpowiedź :).

Co do punktu 2. To jest to o co mi chodziło. Zmodyfikowałem trochę zapytanie, które napisałeś i teraz robi to co chciałem.

Role::whereHas('permissions', function($query) {
            $query->where('name', 'Author');
        })->where(['name'=>'editor'])->count();

Czyli w skrócie sprawdzam czy rola którą posiada użytkownik ma szukane "permission".

Co do punktu 1.

Nie wiem dlaczego ale to zapytanie

User::find($id)->with('role.permissions')->get();

Zwraca mi wszystkich użytkowników z bazy a nie tylko o danym id?

Dlaczego?

komentarz 1 maja 2018 przez KlejnotNilu Użytkownik (750 p.)

Mój błąd. Powinno być:

User::with('role.permissions')->find($id);

 

komentarz 2 maja 2018 przez User007 Bywalec (2,400 p.)
Super! :)

Dziękuję bardzo.

Podobne pytania

0 głosów
1 odpowiedź 408 wizyt
pytanie zadane 17 grudnia 2018 w PHP przez mi-20 Stary wyjadacz (13,190 p.)
0 głosów
1 odpowiedź 303 wizyt
0 głosów
1 odpowiedź 712 wizyt
pytanie zadane 8 czerwca 2017 w SQL, bazy danych przez Rafik Obywatel (1,870 p.)

92,454 zapytań

141,262 odpowiedzi

319,089 komentarzy

61,854 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.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...