Recuperando relaciones de relaciones usando Eloquent en Laravel

3 minutos de lectura

avatar de usuario
ben thompson

Tengo una base de datos con las siguientes tablas y relaciones:

Propaganda 1-1 Coche m-1 Modelo m-1 Marca

Si quiero recuperar un anuncio, simplemente puedo usar:

Advert::find(1);

Si quiero los detalles del auto, podría usar:

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

Sin embargo, si también quiero el detalle del Modelo (siguiendo la relación con Car), cuál sería la sintaxis, lo siguiente no funciona:

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

Muchas gracias

avatar de usuario
Bjorn

esta en el oficial documentación en “Carga ansiosa”

Múltiples relaciones:

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

Relaciones anidadas:

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

Así que para ti:

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

  • ¡Excelente! +1 para referencia a Eager Loading: ¡había revisado la sección Eloquent pero no encontré la respuesta a mi pregunta!

    – Ben Thompson

    23 de septiembre de 2013 a las 15:57

  • ¿Debería funcionar esto también para las relaciones ‘hasMany’? Funciona solo para mis relaciones ‘hasOne’/’belongsTo’.

    – Ben Thompson

    23 de septiembre de 2013 a las 16:04


  • El enlace de la documentación es ahora: laravel.com/docs/5.5/eloquent-relationships#eager-loading en “Carga ansiosa anidada”

    – buzkall

    30/10/2017 a las 17:31

  • Advert::find(1)->with('Car.Model')->get(); en realidad devolverá todos los registros para el anuncio en laravel 8. Advert::with('Car.Model')->find(1); devuelve el específico

    – Bart Mommen

    7 de enero de 2021 a las 14:12


Primero necesitas crear tus relaciones,

<?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');
    }

}

Entonces solo tienes que acceder de esta manera:

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

Pero los campos de tu tabla deberían ser, porque Laravel los adivina de esa manera:

id (for all tables)
car_id
model_id
brand_id

O tendrás que especificarlos en la relación.

Supongamos que tiene 3 modelos región, ciudad, hoteles y para obtener todos los hoteles con ciudad y región, entonces

Defina la relación en ellos de la siguiente manera: –

Hotel.php

class Hotel extends Model {

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

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

Ciudad.php

class City extends Model {

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

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

Región.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();

}

agregará la función de relación solo pedirá la relación necesaria

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

pero si desea una relación anidada, simplemente use el punto en el con

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

pero para relaciones múltiples use la matriz

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

¿Ha sido útil esta solución?