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.