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

Как сделать фильтрацию по связанной таблице Yii2?

Все еще пытаюсь разобраться с фильтрацией...
Есть 3 таблицы: product, size, product_size
Пытаюсь сделать фильтр по размеру - при выборе размера подтягиваются все товары с таким размером. Но как ProductSearch не насиловал ничего не получается.
Product:
/**
     * @return \yii\db\ActiveQuery
     */
    public function getProductSize()
    {
        return $this->hasMany(ProductSize::className(), ['product_id' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getSizes()
    {
        return $this->hasMany(Size::className(), ['id' => 'size_id'])->viaTable('{{%product_size}}', ['product_id' => 'id']);
    }

    private $_sizesArray;

    public function getSizesArray()
    {
        if ($this->_sizesArray === null) {
            $this->_sizesArray = $this->getSizes()->select('id')->column();
        }
        return $this->_sizesArray;
    }

    public function setSizesArray($value)
    {
        $this->_sizesArray = (array)$value;
    }

    public function afterSave($insert, $changedAttributes)
    {
        $this->updateSizes();
        parent::afterSave($insert, $changedAttributes);
    }

    private function updateSizes()
    {
        $currentSizeIds = $this->getSizes()->select('id')->column();
        $newSizeIds = $this->getSizesArray();

        foreach (array_filter(array_diff($newSizeIds, $currentSizeIds)) as $sizeId) {
            /** @var Size $size */
            if ($size = Size::findOne($sizeId)) {
                $this->link('sizes', $size);
            }
        }

        foreach (array_filter(array_diff($currentSizeIds, $newSizeIds)) as $sizeId) {
            /** @var Size $size */
            if ($size = Size::findOne($sizeId)) {
                $this->unlink('sizes', $size, true);
            }
        }
    }


Size
/**
     * @return \yii\db\ActiveQuery
     */
    public function getProductSizes()
    {
        return $this->hasMany(ProductSize::className(), ['size_id' => 'id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getProducts()
    {
        return $this->hasMany(Product::className(), ['id' => 'product_id'])->viaTable('{{%product_size}}', ['size_id' => 'id']);
    }


ProductSize
/**
     * @return \yii\db\ActiveQuery
     */
    public function getProduct()
    {
        return $this->hasOne(Product::className(), ['id' => 'product_id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getSize()
    {
        return $this->hasOne(Size::className(), ['id' => 'size_id']);
    }


ProductSearch
public $productSize;

    public function rules()
    {
        return [
            [['id', 'new', 'hit', 'sale', 'min_price', 'max_price'], 'integer'],
            [['title', 'art', 'meta_key', 'meta_description', 'description', 'image_alt', 'created_at', 'updated_at', 'category_id', 'designer_id', 'price', 'childrenProducts', 'color', 'productSize'], 'safe'],
        ];
    }

    public function scenarios()
    {
        // bypass scenarios() implementation in the parent class
        return Model::scenarios();
    }

    public function search($params)
    {
        $query = Product::find()
            ->from(['p' => Product::tableName()])
            ->with(['designer', 'category'])
            ->joinWith(['productSize'])
            ->orderBy($sort->orders);

        // add conditions that should always apply here

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        $this->load($params);

        if (!$this->validate()) {
            return $dataProvider;
        }

        // grid filtering conditions
        $query->andFilterWhere([
            'p.id' => $this->id,
            'p.designer_id' => $this->designer_id,
            'p.price' => $this->price,
            'p.new' => $this->new,
            'p.hit' => $this->hit,
            'p.sale' => $this->sale,
            'p.color' => $this->color,
            'p.created_at' => $this->created_at,
            'p.updated_at' => $this->updated_at,
            'p.productSize' => $this->productSize,
        ]);


Поле для фильтрации
<?= $form->field($model, 'productSize', ['enableLabel' => false])->dropDownList(Size::find()->select(['name', 'id'])->indexBy('id')->column(), ['prompt' => 'Size']) ?>


Гуглил, доки читал - ниасилил...

Подскажите пожалуйста что я не так делаю? Если можно с примером кода.
А если кому скучно - разжуйте на пальцах, пожалуйста.
  • Вопрос задан
  • 793 просмотра
Решения вопроса 1
webinar
@webinar Куратор тега Yii
Учим yii: https://youtu.be/-WRMlGHLgRg
'p.productSize' => $this->productSize,
вместо "p" я так понимаю надо бы указать имя таблицы, которую дергает связь productSize
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы