• 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.

Object Storage Arubacloud
+1 głos
664 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ź 413 wizyt
pytanie zadane 17 grudnia 2018 w PHP przez mi-20 Stary wyjadacz (13,190 p.)
0 głosów
1 odpowiedź 306 wizyt
0 głosów
1 odpowiedź 744 wizyt
pytanie zadane 8 czerwca 2017 w SQL, bazy danych przez Rafik Obywatel (1,870 p.)

92,554 zapytań

141,399 odpowiedzi

319,535 komentarzy

61,938 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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy 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!

...