Php 具有多个关系的Yii2数据提供程序

Php 具有多个关系的Yii2数据提供程序,php,yii2,yii2-basic-app,yii2-model,Php,Yii2,Yii2 Basic App,Yii2 Model,我尝试构建具有多对多关系的网格视图。因此,我需要查询ActiveDataProvider 我有一个表'ressource',一个表'type',它们之间有一个表'historique' 我在我的模型中有很好的关系,但我不知道如何创建数据提供者 在我的模型资源中: public function getHistorique() { return $this->hasMany(Historique::className(), ['idType' => 'idType']); }

我尝试构建具有多对多关系的网格视图。因此,我需要查询
ActiveDataProvider

我有一个表'ressource',一个表'type',它们之间有一个表'historique'

我在我的模型中有很好的关系,但我不知道如何创建数据提供者

在我的模型资源中:

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']);
}
因此,在控制器(实际上是我的ModelSearch)中,我希望从表historique中获得类型为的Resources。我不知道接下来我要补充什么

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
符号来添加过滤器参数。例如:

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

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

谢谢我没有关闭。我还有最后一个问题:在gridView中,当我使用gridView::widget(['dataProvider'=>$dataProvider])时,它可以工作。但是,当我只想在网格视图中选择其他表中的某些列时,ressource以外的属性是未知的。我应该在gridview的属性中写些什么?@SamaëlVillette您还应该对属性或列名
关系使用点符号。属性
我会试试这个谢谢您的回答,它真的帮助了我:)@SamaëlVillette祝你好运:)请随意选择正确答案,或者在遇到其他问题时添加其他详细信息。我还有一个问题,过滤器无法工作:我添加了
$query->adnFilterWhere(['like','type.nomType',$this->nomType])
然后在gridview中我有如下列:
['label'=>'name','attribute'=>'type.nomType']
我添加了一些规则,但grid view没有任何筛选字段