2016-04-26 3 views
1

Я пытаюсь построить сетку с отношениями «многие ко многим». Поэтому мне нужен запрос для ActiveDataProvider.Yii2 dataprovider with manytomany relation

У меня есть таблица 'ressource', таблица 'type' и между ними таблица 'historyique'.

У меня хорошее отношение к моим моделям, но я не знаю, как создать dataProvider.

В моей модели 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']); 
} 

В моей модели Historique:

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), я хочу иметь ressources с типом из истории таблицы. Я не знаю, что я должен добавить после

Ressource::find(); 

ответ

3

Я думаю, что вы используете 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, чтобы присоединиться к дополнительным отношениям и andFilterWhere с использованием 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'], 
     ]; 
    } 

Вы можете использовать любые дополнительные правила проверки для этого поля

+0

Спасибо, я не был близок. У меня есть только последний вопрос: в gridView, когда я использую GridView :: widget (['dataProvider' => $ dataProvider]), он работает. Но когда я хочу выбрать только несколько столбцов в атрибутах вида сетки из таблицы других, чем ressource, неизвестно. Что мне нужно написать в атрибуте из gridview? –

+1

@ SamaëlVillette вы также должны использовать dot-notation для атрибута или имени столбца 'relation.attribute' –

+0

Я попробую это за ваш ответ, это действительно помогло мне :) –

Смежные вопросы