Я создал такие отношения:
Type.City.Street.House.Apartment
В этом отношении квартира должна зависеть от Дома и от Типа одновременно, поэтому результат sql-запроса должен быть таким:
select * from `apartments` where `apartments`.`house_id` in ('1', '2', '3') and `type_id` = '777'
Проблема в том, что отношение HasManyThrough рассматривает только два уровня, и с его помощью невозможно добраться до самой первой модели.
Посоветуйте, пожалуйста, как это можно сделать?
Мои определения моделей:
class Type extends Model {
public function city() {
return $this->hasMany('App\City');
}
}
class City extends Model {
public function street() {
return $this->hasMany('App\Street');
}
}
class Street extends Model {
public function house() {
return $this->hasMany('App\House');
}
}
class House extends Model {
public function Apartment() {
return $this->hasMany('App\Apartment');
//->where('type_id', '=' type.id) ?????
}
}
class Apartment extends Model {
public $fillable = ['house_id', 'type_id']
}






Я бы добавил отображение для house_id в модели Apartment и установил двунаправленные сопоставления между вашими моделями.
class Apartment extends Model {
public $fillable = ['house_id', 'type_id'];
public function house() {
return $this->belongsTo('App\House', 'house_id');
}
}
class Type extends Model {
public function city() {
return $this->hasMany('App\City');
}
}
class City extends Model {
public function type() {
return $this->belongsTo('App\Type', 'type_id');
}
public function street() {
return $this->hasMany('App\Street');
}
}
class Street extends Model {
public function city() {
return $this->belongsTo('App\City', 'city_id');
}
public function house() {
return $this->hasMany('App\House');
}
}
class House extends Model {
public function street() {
return $this->belongsTo('App\Street', 'street_id');
}
public function Apartment() {
return $this->hasMany('App\Apartment');
//->where('type_id', '=' type.id) ?????
}
}
тогда вы можете запросить апартаменты в соответствии с вашими критериями, например
Apartments::whereHas('house.street.city.type', function ($query) use ($type_id) {
$query->where('id', '=', $type_id);
})
->whereHas('house', function ($query) use ($house_ids) {
$query->whereIn('id', $house_ids);
});
И я думаю, что в модели type_id нет необходимости в Apartments.
Спасибо. Не OP, но я не знал о том, где такая цепочка. Вы только что помогли мне упростить кучу кода!
Я создал отношения HasManyThrough с неограниченным количеством уровней: Репозиторий на GitHub
После установки вы можете использовать его так:
class Type extends Model {
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function Apartment() {
return $this->hasManyDeep(Apartment::class, [City::class, Street::class, House::class])
->where('apartments.type_id', $this->id);
}
}
К сожалению, это не работает с активной загрузкой.
Ух ты! Большой! Я попробую это в ближайшее время
Опубликуйте определения вашей модели