You have 3 options using relationships:
1 most simple solution:
Places::whereHas('contacts',function ($q) use ($city_id){ $q->whereHas('cities', function ($q) use ($city_id){ $q->where('id', $city_id); }); })->get();
2 is the same as above, but using this PR: https://github.com/laravel/framework/pull/4954
Places::whereHas('contacts.cities', function ($q) use ($city_id){ $q->where('id', $city_id); })->get();
3 Using the hasManyThrough relation:
// Place model public function cities() { return $this->hasManyThrough('City', 'Contact'); } // then Places::whereHas('cities',function ($q) use ($city_id){ $q->where('cities.id', $city_id); })->get();
change
Having your own scheme, it is obvious that none of the proposed or initial settings can work.
This is a many-to-many relationship, which in Eloquent belongsToMany :
// Places model public function cities() { return $this->belongsToMany('Cities', 'contacts', 'places_id', 'cities_id') ->withPivot( .. contacts table fields that you need go here.. ); } // Cities model public function places() { return $this->belongsToMany('Places', 'contacts', 'cities_id', 'places_id') ->withPivot( .. contacts table fields that you need go here.. ); }
Then you can call the following relationships:
$city = Cities::first(); $city->places;
Now, there is another way to configure this if you need the Contacts model itself:
// Places model public function contact() { return $this->hasOne('Contacts', 'places_id'); } // Contacts model public function city() { return $this->belongsTo('Cities', 'cities_id'); } public function place() { return $this->belongsTo('Places', 'places_id'); } // Cities model public function contact() { return $this->hasOne('Contacts', 'cities_id'); }
then
$city = Cities::first(); $city->contact; // Contacts model $city->contact->place; // Places model
hasManyThrough will not work at all