具有多对多关系的 Yii2 数据提供者


Yii2 dataprovider with manytomany relation

我尝试构建具有多对多关系的网格视图。所以我需要一个查询ActiveDataProvider.

我有一个表"资源",一个表"类型",它们之间有一个表"历史"。

我的模型中关系很好,但我不知道如何创建数据提供程序。

在我的模型中 资源 :

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']);   
}

在我的模型中 历史 :

public function getType()
{
    return $this->hasOne(Type::className(), ['idType' => 'idType']);
}
public function getRessource()
{
    return $this->hasOne(Ressource::className(), ['idRessource' => 'idRessource']);
}

最后在我的模型中 类型:

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']);
}

因此,在控制器(实际上是我的模型搜索)中,我希望从表历史中获得类型的资源。我不知道之后我必须添加什么

Ressource::find();

我认为您使用RessourceSearch()->search()方法。所以在里面你有这样的东西:

$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;

因此,基本上,您需要在查询中添加其他Where并强制联接关系表。您可以使用joinWith方法联接其他关系,并使用table.field表示法添加过滤器参数andFilterWhere执行此操作。例如:

$query = Ressource::find();
$query->joinWith(['historique', 'type']);
$query->andFilterWhere(['like', 'type.type', $this->type]);
$query->andFilterWhere(['like', 'historique.historique_field', $this->historique_field]);

此外,不要忘记为搜索模型中的其他筛选器添加规则。例如上面,您应该在rules()数组中添加类似以下内容:

public function rules()
    {
        return [
            // here add attributes rules from Ressource model
            [['historique_field', 'type'], 'safe'],
        ];
    }

您可以对该字段使用任何其他验证规则