49

I have a database with the following tables and relationships:

Advert 1-1 Car m-1 Model m-1 Brand

If I want to retrieve an Advert, I can simply use:

Advert::find(1);

If I want the details of the car, I could use:

Advert::find(1)->with('Car');

However, if I also want the detail of the Model (following the relationship with Car), what would the syntax be, the following doesn't work:

Advert::find(1)->with('Car')->with('Model');

Many thanks

Ben Thompson
  • 4,743
  • 7
  • 35
  • 52

4 Answers4

143

It's in the official documentation under "Eager Loading"

Multiple relationships:

$books = Book::with('author', 'publisher')->get();

Nested relationships:

$books = Book::with('author.contacts')->get();

So for you:

Advert::with('Car.Model')->find(1);
Björn
  • 5,696
  • 1
  • 24
  • 34
  • Ah excellent! +1 for reference to Eager Loading - I had been through the Eloquent section but not found the answer to my question! – Ben Thompson Sep 23 '13 at 15:57
  • Should this work for 'hasMany' relationships as well? It is working for my 'hasOne'/'belongsTo' relationships only. – Ben Thompson Sep 23 '13 at 16:04
  • 3
    The documentation link is now: https://laravel.com/docs/5.5/eloquent-relationships#eager-loading under "Nested Eager Loading" – buzkall Oct 30 '17 at 17:31
  • 1
    `Advert::find(1)->with('Car.Model')->get();` will actually return all records for advert in laravel 8. `Advert::with('Car.Model')->find(1);` returns the specific one – Bart Mommens Jan 07 '21 at 14:12
7

First you need to create your relations,

<?php

class Advert extends Eloquent {

    public function car()
    {
        return $this->belongsTo('Car');
    }

}

class Car extends Eloquent {

    public function model()
    {
        return $this->belongsTo('Model');
    }

}

class Model extends Eloquent {

    public function brand()
    {
        return $this->belongsTo('Brand');
    }

    public function cars()
    {
        return $this->hasMany('Car');
    }

}

class Brand extends Eloquent {

    public function models()
    {
        return $this->hasMany('Model');
    }

}

Then you just have to access this way:

echo Advert::find(1)->car->model->brand->name;

But your table fields shoud be, because Laravel guess them that way:

id (for all tables)
car_id
model_id
brand_id

Or you'll have to specify them in the relationship.

Antonio Carlos Ribeiro
  • 86,191
  • 22
  • 213
  • 204
2

Suppose you have 3 models region,city,hotels and to get all hotels with city and region then

Define relationship in them as follows:-

Hotel.php

class Hotel extends Model {

  public function cities(){
        return $this->hasMany(City::class);
  }

  public function city(){
        return $this->belongsTo('App\City','city_id');
  }
}

City.php

class City extends Model {

  public function hotels(){
      return $this->hasMany(Hotel::class);
  }

  public function regions(){
      return $this->belongsTo('App\Region','region_id');    
  }
}

Region.php

class Region extends Model
{

  public function cities(){
      return $this->hasMany('App\City');    
  }

  public function country(){
      return $this->belongsTo('App\Country','country_id');
  } 
}

HotelController.php

public function getAllHotels(){
    // get all hotes with city and region
    $hotels = Hotel::with('city.regions')->get()->toArray();

}
2

will adding the relation function just ask for the relation needed

public function Car()
{
    return $this->belongsTo(Car::class, 'car_id')->with('Model');
}

but if you want a nested relation just use the period in the with

Advert::with('Car.Model')->find(1);

but for multi-relation use the array

Advert::with('Car','Model')->find(1);
Hisham Shami
  • 439
  • 4
  • 8