I have many-to-many relation with three tables: Category
, Product
, ProductCategory
.
Relation in Category
:
public function getProductCategories()
{
return $this->hasMany(ProductCategory::className(), ['category_id' => 'id']);
}
Relation in Product
:
public function getProductCategories()
{
return $this->hasMany(ProductCategory::ClassName(), ['product_id' => 'id']);
}
And in ProductCategory
public function getProduct()
{
return $this->hasOne(Product::className(), ['id' => 'product_id']);
}
public function getCategory()
{
return $this->hasOne(Category::className(), ['id' => 'category_id']);
}
In my Category Controller I used this code to show the products I need according to their category (one-to-many):
$cats = Category::findOne(['slug1'=>$slug1]);
$dataProvider = new ActiveDataProvider([
'query' => $query = Product::find()->where(['category_id' => $cats->id]),
'sort'=>array(
'defaultOrder'=>['id' => SORT_ASC],
),
'pagination' => [
'pageSize' => 9,
],
]);
So the question is how to make my ActiveDataProvider to get in query the many-to-many relation?
You can create two more relations like this
In category:
public function getProducts()
{
return $this->hasMany(Product::className(), ['id' => 'product_id'])->via("productCategories");
}
And in product:
public function getCategories()
{
return $this->hasMany(Category::ClassName(), ['id' => 'category_id'])->via("productCategories");
}
Then you can use it like this
$cats = Category::findOne(['slug1'=>$slug1]);
$dataProvider = new ActiveDataProvider([
'query' => $query = $cats->getProducts(),
'sort'=>array(
'defaultOrder'=>['id' => SORT_ASC],
),
'pagination' => [
'pageSize' => 9,
],
]);