Answer the question
In order to leave comments, you need to log in
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);
}
}
}
/**
* @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']);
}
/**
* @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']);
}
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']) ?>
Answer the question
In order to leave comments, you need to log in
'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 questionAsk a Question
731 491 924 answers to any question