Search code examples
laravel-5eloquenthas-many-throughlumenbelongs-to

lumen/laravel Eloquent hasManyThrough 3 models relation


I try to acomplish a relation with 3 models:

Cities.php //table cities
id
name

Neighbourhoods.php //table neighbourhoods
id
name
city_id

Blocks.php //table blocks
id
name
neighbourhood_id

My models looks like this: Cities.php

public function neighbourhoods()
{
    return $this->hasManyThrough('App\Neighbourhoods', 'App\Blocks', 'neighbourhood_id', 'city_id', 'id');
}

Neighbourhoods.php

public function blocks()
{
    return $this->hasMany('App\Blocks', 'neighbourhood_id', 'id');
}

Blocks.php

public function neighbourhoods()
{
    return $this->belongsToMany('App\Neighbourhoods', 'neighbourhood_id', 'id');
}

The result shoud be:

results
 city1:
  neighbourhoods:
   neighbourhood1:
    block1
    block2
    block3
   neighbourhood2
    block1
    block2
 city2:
  neighbourhoods:
   neighbourhood1:
    blocks:
     block1
     block2
     block3
   neighbourhood2:
    blocks:
     block1
     block2

Calling the results:

return Blocks::with('neighbourhoods')->get();

I know that my models are not properly named. City (singular), Neighbourhood (singlar), Block (singular) but passing parameters shoud work. I just can't figure our why it does not work.

RELATIONSSHIP SOLUTION based on @Gaurav Rai's response

First of all, my models are wrong named. Please condider naming your database using plurals for example: cities, neighbourhoods, blocks and your models singular for example: City.php, Neighbourhood.php and Block.php

Based on my problem, the solution is:

Cities.php

public function neighbourhoods()
{
    return $this->hasMany('App\Neighbourhoods', 'city_id', 'id');
     // because my model is called Cities.php,
     // the function will look by default 
     // for the column cities_id in neighbourhoods table, 
     // thats why we need to specifiy city_id column
}

public function blocks()
{
    return $this->hasManyThrough('App\Blocks', 'App\Neighbourhoods', 'city_id', 'neighbourhood_id', 'id');
}

Neighbourhoods.php

public function cities()
{
    return $this->belongsTo('App\Cities', 'city_id', 'id');
}

public function blocks()
{
    return $this->hasMany('App\Blocks', 'neighbourhood_id','id');
}

Blocks.php

public function neighbourhoods()
{
    return $this->belongsTo('App\Neighbourhoods', 'neighbourhood_id');
}

Calling the relation:

return Cities::with(['neighbourhoods', 'blocks'])->get();

Solution

  • I think your relationships are not well defined:

    Cities.php

    public function neighbourhoods()
    {
        return $this->hasMany('App\Neighbourhoods');
    }
    public function blocks()
    {
        return $this->hasManyThrough('App\Neighbourhoods', 'App\Blocks');
    }
    

    Neighbourhoods.php

    public function blocks()
    {
        return $this->hasMany('App\Blocks');//by default it will consider id
    }
    public function city()
    {
        return $this->belongsTo('App\City');
    }
    

    Blocks.php

    public function neighbourhoods()
    {
        return $this->belongsTo('App\Neighbourhoods');
    }