Przypomnienie teoretyczne wszystkich relacji, jakie dotąd poznaliśmy w Laravelu. Ważna lekcja utrwalająca zdobytą wiedzę.
Relacja jeden do jednego – łączy ze sobą dwa modele, z których jeden jest rodzicem, a drugi dzieckiem:
- Model rodzic nie posiada żadnego klucza obcego
- Model dziecko posiada klucz obcy wskazujący na rodzica
- Model rodzic posiada metodę hasOne z klasą dziecka
- Model dziecko posiada metodę belongsTo z klasą rodzica
One to one od strony rodzica:
public function contact(){
return $this->hasOne(Contact::class);
}
One to one od strony dziecka (model z contact_id):
public function profile(){
return $this->belongsTo(Profile::class);
}
Relacja jeden do wielu – łączy ze sobą jeden model rodzica z wieloma modelami dziećmi:
- Model rodzic nie posiada klucza obcego
- Model dziecko posiada klucz obcy pokazujący rodzica
- Model rodzic posiada metodę hasMany z klasą dziecka
- Model dziecko posiada metodę belongsTo z klasą rodzica
Relacja jeden do wielu od strony rodzica:
public function types(){
return $this->hasMany(Type::class);
}
Relacja jeden do wielu od strony dziecka (model z category_id):
public function category(){
return $this->belongsTo(Category::class);
}
Relacja jeden z wielu – relacja modelu, który ma już relację hasMany (zazwyczaj), ale daje pojedyncze rekordy z tego hasMany w różnych metodach jako hasOne:
- Rodzic może użyć hasOne i ->latest albo ->oldest
- Rodzic może wskazać kolumnę dziecka i funkcję sortującą, która ma wyciągnąć jeden z wielu
Relacja jeden do wielu + jeden z wielu od strony rodzica:
public function reviews(){
return $this->hasMany(Review::class);
}
public function latestReview()
{
return $this->hasOne(Review::class)->latestOfMany();
}
public function oldestReview()
{
return $this->hasOne(Review::class)->oldestOfMany();
}
public function worstReview()
{
return $this->hasOne(Review::class)->ofMany('rating', 'min');
}
public function bestReview()
{
return $this->hasOne(Review::class)->ofMany('rating', 'max');
}
Relacja jeden do wielu od strony modelu dziecka (ten, co ma movie_id), który nic nie wie o relacjach jeden z wielu swojego rodzica:
public function movie(){
return $this->belongsTo(Movie::class);
}
Relacja wiele do wielu – relacja równorzędna, w której wiele modeli jednego typu jest połączonych z wieloma modelami drugiego typu przy pomocy tabeli piwotalnej:
- po obu stronach relacji mamy metodę ->belongsToMany pokazującą drugą stronę relacji
- tabela piwotalna zawiera dwa klucze obce, jeden wskazujący na jedną stronę, drugi na drugą stronę relacji
Relacja wiele do wielu od strony jednej i drugiej:
//Review
public function tags(){
return $this->belongsToMany(Tag::class)->withTimestamps();
}
//Tag
public function reviews(){
return $this->belongsToMany(Review::class)->withTimestamps();
}
Tabela piwotalna zawiera tag_id oraz review_id i pary tych rekordów tworzą relację. Do tabeli piwotalnej można się odnieść przez ->pivot, można też zmienić nazwę piwota przez ->as na belongsToMany (tak jak dodaliśmy obsługę timestamps).
Relacja jeden przez – relacja jeden do jednego przez pośrednika, który znajduje się w relacji jeden do jednego. Przykład:
public function profile(){
return $this->hasOne(Profile::class);
}
public function profileContact()
{
return $this->hasOneThrough(Contact::class, Profile::class);
}
Profil ma relację hasOne do Contact, zaś Person poprzez profile, które posiada, uzyskuje także dostęp do Contact.
Relacja wiele przez – relacja jeden do wielu przez pośrednika. Przykład:
public function types(){
return $this->hasMany(Type::class);
}
public function items()
{
return $this->hasManyThrough(Item::class, Type::class);
}
Category posiada types, zaś types jest w relacji hasMany do Item. Category uzyskuje dostęp do Item poprzez Type będące w relacji hasMany do Item.
Robiliśmy jeszcze relacje polimorficzne, ale je sobie na razie darujemy, upewnijmy się, że to rozumiemy.