I do a sample of the city, the city has areas, they have complexes, and the complexes have apartments. In the end, I need to get apartments for a particular city, indicating the associated filters (district, complex, etc.). At the moment I did this:

public function actionIndex() { $cities = Cities::find()->where(['id' => Yii::$app->request->get('city_id')])->with([ 'districts' => function ($query){ $query->filterWhere([ 'id' => Yii::$app->request->get('district_id'), ]); }, 'districts.complexes' => function ($query) { $query->filterWhere([ 'id' => Yii::$app->request->get('complex_id'), 'type_id' => Yii::$app->request->get('complex_type_id'), 'developer_id' => Yii::$app->request->get('developer_id'), ]); }, 'districts.complexes.apartments' => function ($query) { $query->filterWhere([ 'amount_room' => Yii::$app->request->get('amount_room'), 'yardage' => Yii::$app->request->get('yardage'), 'level' => Yii::$app->request->get('level'), 'price' => Yii::$app->request->get('price'), ]); }, ])->all(); $query = []; foreach ($cities as $city) { foreach ($city->districts as $district) { foreach ($district->complexes as $complex) { foreach ($complex->apartments as $apartment) { $query[] = $apartment; } } } } return new ArrayDataProvider([ 'allModels' => $query, ]); } 

But it looks like a crutch, maybe I went the wrong way, and can I do better?

  • one
    good day. went the wrong way. It is necessary in the models to make connections of the tables through hasMany or hasOne and then just call the model of the area and the rest everything will be tightened by itself and you will get one large array. Doing 4 foreach is not cool at all. - SOFQ3
  • @ SOFQ3, So there are connections, and I’m just calling for them, but one city has many districts, and each of these areas has many complexes, and they have many apartments. 4 foreach confuses the most, therefore asked a question here. How exactly can I get rid of the foreach bulkhead? - edvardpotter
  • so what should be the final result? Why get all these apartments? - SOFQ3
  • You need to get apartments (apartments) in the whole city. - edvardpotter
  • and if you try to choose not the city as it is now, but the apartments and make a bundle to the city and then group them around the city, we will get all the apartments in the city. - SOFQ3

1 answer 1

Found this solution:

 public function actionIndex() { $query = Apartment::find() ->joinWith('complex') ->joinWith('complex.district') ->joinWith('complex.district.city') ->where(['cities.id' => Yii::$app->request->get('city_id')]) ->filterWhere(['districts.id' => Yii::$app->request->get('district_id')]) ->filterWhere(['complex.id' => Yii::$app->request->get('complex_id')]) ->filterWhere(['complex.type_id' => Yii::$app->request->get('complex_type_id')]) ->filterWhere(['complex.developer_id' => Yii::$app->request->get('developer_id')]) ->filterWhere(['apartment.amount_room' => Yii::$app->request->get('amount_room')]) ->filterWhere(['apartment.yardage' => Yii::$app->request->get('yardage')]) ->filterWhere(['apartment.level' => Yii::$app->request->get('level')]) ->filterWhere(['apartment.price' => Yii::$app->request->get('price')]); return new ActiveDataProvider([ 'query' => $query, ]); }