I try to build a grid view with many-to-many relations. So I need a query for the ActiveDataProvider
.
I have a table 'ressource', a table 'type' and between them a table 'historique'.
I have the good relation in my models but I don't know how to create the dataProvider.
In my model Ressource :
public function getHistorique()
{
return $this->hasMany(Historique::className(), ['idType' => 'idType']);
}
public function getType()
{
return $this->hasMany(Type::className(), ['idType' => 'idType'])
->viaTable(Historique::className(), ['idRessource' => 'idRessource']);
}
In my model Historique :
public function getType()
{
return $this->hasOne(Type::className(), ['idType' => 'idType']);
}
public function getRessource()
{
return $this->hasOne(Ressource::className(), ['idRessource' => 'idRessource']);
}
and finally in my model Type :
public function getHistorique()
{
return $this->hasMany(Historique::className(), ['idType' => 'idType']);
}
public function getRessource()
{
return $this->hasMany(Ressource::className(), ['idRessource' => 'idRessource'])
->viaTable(Historique::className(), ['idType' => 'idType']);
}
So in the Controller (in fact my ModelSearch), I want to have ressources with type from the table historique. I don't know what I have to add after
Ressource::find();
I think you use RessourceSearch()->search()
method. So inside it you have something like this:
$query = Ressource::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
// Here is list of searchable fields of your model.
$query->andFilterWhere(['like', 'username', $this->username])
->andFilterWhere(['like', 'auth_key', $this->auth_key])
return $dataProvider;
So, basically, you need to add additional Where
you your query and force to join relation table. You can do that using joinWith
method to join additional relation and andFilterWhere
using table.field
notation for adding filter parameters. For example:
$query = Ressource::find();
$query->joinWith(['historique', 'type']);
$query->andFilterWhere(['like', 'type.type', $this->type]);
$query->andFilterWhere(['like', 'historique.historique_field', $this->historique_field]);
Also do not forget to add rules for additional filters in your search model. For example above, you should add to your rules()
array something like that:
public function rules()
{
return [
// here add attributes rules from Ressource model
[['historique_field', 'type'], 'safe'],
];
}
You can use any additional validation rules for that fields