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

+1 głos
180 wizyt
pytanie zadane 30 kwietnia 2018 w PHP, Symfony, Zend przez User007 Obywatel (1,960 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 Obywatel (1,960 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 Obywatel (1,960 p.)
Super! :)

Dziękuję bardzo.

Podobne pytania

0 głosów
1 odpowiedź 72 wizyt
pytanie zadane 17 grudnia 2018 w PHP, Symfony, Zend przez mi-20 Stary wyjadacz (10,460 p.)
0 głosów
1 odpowiedź 85 wizyt
0 głosów
1 odpowiedź 115 wizyt
pytanie zadane 8 czerwca 2017 w SQL, bazy danych przez Rafik Obywatel (1,870 p.)
Porady nie od parady
Możesz ukryć, zamknąć lub zmodyfikować swoje pytanie, za pomocą przycisków znajdujących się pod nim. Nie krępuj się poprawić pochopnie opublikowanego pytania czy zamknąć go po uzyskaniu satysfakcjonującej odpowiedzi. Umożliwi to zachowanie porządku na forum.Przyciski pytania

66,494 zapytań

113,266 odpowiedzi

239,865 komentarzy

46,631 pasjonatów

Przeglądających: 102
Pasjonatów: 2 Gości: 100

Motyw:

Akcja Pajacyk

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

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...