У меня есть таблицы: document
и document_content
. One
документ может иметь many
содержание.
Я использую метод joinWith()
для получения данных из таблицы document_content
вместе с document
с использованием отношений модели.
Выполняемые запросы следующие:
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)
У меня проблема с этим вторым запросом. Я хочу, чтобы он включал это предложение WHERE из первого: WHERE (lang='1')
Итак, я хочу, чтобы yii сгенерировал этот запрос:
SELECT * FROM document_content WHERE (lang='1') AND document_id IN (665566, 665034, 664961, 664918, 664910, 664898, 664896, 664893, 664882, 664880)
Мне как-то удалось этого добиться, но у меня есть повторение кода, и мне это не нравится. Должен быть какой-то лучший способ сделать это. Это мой код, который работает, но я думаю, что это не так хорошо:
/**
* 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;
}
Как видите, я проверяю params['lang']
в двух местах. В моем методе отношения и в методе buildDocumentContentQuery()
. Поэтому я повторяю один и тот же код в двух местах, и параметр lang не будет единственным, который я хочу протестировать, их может быть 10 или больше.
По сути, мне пришлось сделать все это, потому что я не мог отправить какие-либо параметры через метод yii2 joinWith()
. Я не знаю, как лучше всего добавить WHERE
к запросу, сгенерированному при нетерпеливой загрузке joinWith()
. Я как-то заставил это работать, но я думаю, что это грязно.
Есть ли у кого-нибудь идеи для лучшего/более чистого решения этой проблемы?