A
A
Alexander Stepanov2018-02-22 19:00:35
Yii
Alexander Stepanov, 2018-02-22 19:00:35

How to filter by related Yii2 table?

I'm still trying to figure out how to filter...
There are 3 tables: product, size, product_size.
I'm trying to make a filter by size - when choosing a size, all products with that size are pulled up. But as ProductSearch did not rape, nothing happens.
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,
        ]);

Field to filter
<?= $form->field($model, 'productSize', ['enableLabel' => false])->dropDownList(Size::find()->select(['name', 'id'])->indexBy('id')->column(), ['prompt' => 'Size']) ?>

Googled, read the docks - niasilil ...
Please tell me what I'm doing wrong? If possible with a code example.
And if anyone is bored - chew on your fingers, please.

Answer the question

In order to leave comments, you need to log in

[[+comments_count]] answer(s)
M
Maxim Timofeev, 2018-02-22
@Exebeche

'p.productSize' => $this->productSize,
instead of "p", as I understand it, it would be necessary to specify the name of the table that the productSize link pulls

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question