Exebeche
@Exebeche
Осваиваю программирование

Как выводить посты из дочерних категорий в фильтре gridView/listView фреймворка Yii2?

Имеется сайт с категориями и постами. Категории могут быть очерними и родительскими по 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)]);
}


Но как не пытался его вставить, модернизировать никакого результата.
Очень нужно разобраться
  • Вопрос задан
  • 114 просмотров
Решения вопроса 1
  • Exebeche
    @Exebeche
    Осваиваю программирование
    Помогли решить на воркзиле
    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;
        }
    Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы