• 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
172 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ź 67 wizyt
pytanie zadane 17 grudnia 2018 w PHP, Symfony, Zend przez mi-20 Stary wyjadacz (10,380 p.)
0 głosów
1 odpowiedź 82 wizyt
0 głosów
1 odpowiedź 114 wizyt
pytanie zadane 8 czerwca 2017 w SQL, bazy danych przez Rafik Obywatel (1,870 p.)
Porady nie od parady
Forum posiada swój własny chat IRC, dzięki któremu będziesz mógł po prostu pogadać z innymi Pasjonatami lub zapytać o jakiś problem. Podstrona z chatem znajduje się w menu pod ikoną człowieka w dymku.IRC

65,755 zapytań

112,393 odpowiedzi

237,319 komentarzy

46,700 pasjonatów

Przeglądających: 120
Pasjonatów: 0 Gości: 120

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.

...