Answer the question
In order to leave comments, you need to log in
How to display posts from child categories in Yii2 gridView/listView filter?
There is a site with categories and posts. Categories can be child and parent by parent_id. Everything works fine, except for one thing with filtering - when you select a parent category in the filter, you need to display posts from child categories. He suffered for a long time, but niasilil.
Created a viatable connection and wardump everything is beautifully displayed from the model, but when choosing a parent in grid / listView, I get empty-empty
Model 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']);
}
/**
* @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']);
}
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;
}
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;
}
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)]);
}
Answer the question
In order to leave comments, you need to log in
Helped solve on workzilla
public function search($params)
{
$query = Product::find()
->from(['p' => Product::tableName()])
->with(['designer', 'category']);
// 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([
'p.id' => $this->id,
//'p.category_id' => $this->category_id,
'p.designer_id' => $this->designer_id,
'p.price' => $this->price,
'p.new' => $this->new,
'p.hit' => $this->hit,
'p.sale' => $this->sale,
'p.created_at' => $this->created_at,
'p.updated_at' => $this->updated_at,
// 'p2.childrenProducts' => $this->category_id
]);
if (!empty($this->category_id)) {
$ids = Category::find()->andWhere(['parent_id'=>[$this->category_id]])->alias('p2')->column();
$ids[] = $this->category_id;
$query->andWhere(['p.category_id' => array_unique($ids)]);
}
$query->andFilterWhere(['like', 'title', $this->title])
->andFilterWhere(['like', 'art', $this->art])
->andFilterWhere(['like', 'meta_key', $this->meta_key])
->andFilterWhere(['like', 'meta_description', $this->meta_description])
->andFilterWhere(['like', 'description', $this->description])
->andFilterWhere(['like', 'image_alt', $this->image_alt]);
return $dataProvider;
}
Instead ,
apparently it is necessary
. Since you do not need eager loading of individual requests, but join
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question