Все еще пытаюсь разобраться с фильтрацией...
Есть 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']) ?>
Гуглил, доки читал - ниасилил...
Подскажите пожалуйста что я не так делаю? Если можно с примером кода.
А если кому скучно - разжуйте на пальцах, пожалуйста.