2016-04-07 11 views
0

Ich habe Tabellen: document und document_content. One Dokument kann many Inhalt haben.Wie man WHERE in yii2 joinWith() verwendet, das eifrig lädt

Ich verwende joinWith() Methode, um Daten aus document_content Tabelle zusammen mit document mit Modellrelationen zu erhalten.

Die ausgeführten Abfragen sind diese:

SELECT document.* FROM document INNER JOIN document_content ON document.id = document_content.document_id WHERE (lang='1') ORDER BY id DESC LIMIT 10

SELECT * FROM document_content WHERE document_id IN (665566, 665034, 664961, 664918, 664910, 664898, 664896, 664893, 664882, 664880)

Ich habe ein Problem mit dieser zweiten Abfrage. Ich will es diese WHERE-Klausel von der ersten gehören: WHERE (lang='1')

Deshalb möchte ich yii diese Abfrage generieren:

SELECT * FROM document_content WHERE (lang='1') AND document_id IN (665566, 665034, 664961, 664918, 664910, 664898, 664896, 664893, 664882, 664880)

ich irgendwie, dies zu erreichen haben es geschafft, aber ich habe Code Wiederholung und Ich mag es nicht. Es muss einen besseren Weg geben, dies zu tun. Dies ist mein Code, der funktioniert, aber es ist nicht so gut, denke ich:

/** 
* Returns documents by params. 
* 
* @param array $params the query params. 
* @return ActiveDataProvider 
*/ 
public function findDocuments($params) 
{ 
    /** @var $query ActiveQuery */ 
    $query = Document::find(); 

    // store params to use in other class methods. 
    self::$_params = $params; 

    // build dynamic conditions for document table 
    $this->buildDocumentQuery($query); 

    // build dynamic conditions for document_content table 
    $this->buildDocumentContentQuery($query); 

    // add conditions that should always apply here 
    $dataProvider = new ActiveDataProvider([ 
     'query' => $query, 
     'sort' => ['defaultOrder' => ['id' => SORT_DESC]], 
     'pagination' => [ 
      'pageSize' => 10, 
     ], 
    ]); 

    return $dataProvider; 
} 

/** 
* Relation with document_content table. 
* 
* @return DocumentContent 
*/ 
public function getDocumentContent() 
{ 
    $query = $this->hasMany(DocumentContent::className(), ['document_id' => 'id']); 

    if (isset(self::$_params['lang'])) { 
     $query->andFilterWhere([ 
      'lang' => self::$_params['lang'], 
     ]); 
    } 
} 

/** 
* Method that is responsible for building query conditions for document_content table. 
* 
* @param object $query ActiveQuery instance. 
* @return ActiveQuery 
*/ 
public function buildDocumentContentQuery($query) 
{ 
    if (isset(self::$_params['lang'])) { 
     $query->innerJoinWith('documentContent'); 
    } 

    return $query; 
} 

Wie man sehen kann ich für params['lang'] an zwei Stellen bin Überprüfung. In meiner Beziehung Methode und in buildDocumentContentQuery() Methode. Also wiederhole ich denselben Code an zwei Stellen, und lang param wird nicht der einzige sein, den ich testen möchte, es können 10 oder mehr sein.

Grundsätzlich musste ich all dies tun, weil ich keine Parameter durch yii2 joinWith() Methode senden konnte. Ich weiß nicht, was ist der beste Weg, um WHERE Abfrage hinzufügen, die durch eifriges Laden von joinWith() generiert wird. Ich habe es irgendwie funktionieren lassen, aber ich denke, das ist dreckig.

Hat jemand eine Idee für bessere/sauberere Lösung für dieses Problem?

Antwort

0

Model # Dokument

public function getDocuments($params) 
{ 
    /** @var $query ActiveQuery */ 
    $query = Document::find(); 
    $query->getDocumentContentsByLanguage($params['lang']); 
} 

public function getDocumentContentsByLanguage($lang = null) 
{ 
    return $this->hasMany(DocumentContent::className(), ['document_id' => 'id'])->where('lang = :lang', [':lang'=>$lang]); 
} 
0

Try this:

$query = $this 
    ->hasMany(DocumentContent::className(), ['document_id' => 'id']); 

if (isset(self::$_params['lang']) && self::$_params['lang']==1) { 
    $query 
     ->joinWith('document') 
     ->andWhere([ 
      Document::tablename().'.lang' => self::$_params['lang'] 
     ]); 
} 
Verwandte Themen