Имеется сайт с категориями и постами. Категории могут быть очерними и родительскими по parent_id. Все прекрасно работает, за исключением одного момента с фильтрацией - при выборе в фильтре родительской категории нужно выводить посты из дочерних категорий. Долго мучился, но так и ниасилил.
Создал связь виатабле и вардампом все красиво выводится из модели, но при выборе родителя в grid/listView получю пусто-пусто
Модель Category
/**
* @return \yii\db\ActiveQuery
*/
public function getParent()
{
return $this->hasOne(Category::className(), ['id' => 'parent_id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getCategories()
{
return $this->hasMany(Category::className(), ['parent_id' => 'id'])->with('posts');
}
/**
* @return \yii\db\ActiveQuery
*/
public function getPost()
{
return $this->hasMany(Post::className(), ['category_id' => 'id']);
}
public function getChildrenPosts()
{
return $this->hasMany(Post::className(), ['category_id' => 'id'])->indexBy('id')->asArray()->viaTable('{{%category}}', ['parent_id' =>'id']);
}
Модель Post
/**
* @return \yii\db\ActiveQuery
*/
public function getCategory()
{
return $this->hasOne(Category::className(), ['id' => 'category_id']);
}
public function getChildrenPosts()
{
return $this->hasMany(Post::className(), ['category_id' => 'id'])->indexBy('id')->asArray()->viaTable('{{%category}}', ['parent_id' =>'id']);
}
Модель PostSearch
public function search($params)
{
$query = Post::find()->with(['category', 'childrenPosts']);
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'category_id' => $this->category_id,
'content' => $this->content,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]);
return $dataProvider;
}
Модель CategorySearch
public function search($params)
{
$query = Category::find()
->select(['{{%category}}.*', 'posts_count' => new Expression('COUNT({{%post}}.id)')])
->joinWith(['post'], false)
->groupBy('{{%category}}.id')
->with(['parent', 'childrenPosts']);
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'parent_id' => $this->parent_id,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]);
return $dataProvider;
}
Как видно из кода - пытался изо всех сил пристроить childrenPosts, но все без успешно. Пожалуйста, подскажите, что я где не так и объясните, пожалуйста, как нужно сделать чтобы было правильно.
З.Ы. Желательно своими словами т.к.прочитанное и просмотренное ранее не принесло результата :( Получил ответ от Дмитрия Елисеева:
if (!empty($this->category_id)) {
$ids = [$this->category_id];
$childrenIds = $ids;
while ($childrenIds = Category::find()->select('id')->andWhere(['parent_id' => $childrenIds])->column()) {
$ids = array_merge($ids, $childrenIds);
}
$query->andWhere(['category_id' => array_unique($ids)]);
}
Но как не пытался его вставить, модернизировать никакого результата.
Очень нужно разобраться