Вы не можете создать регулярное отношение таким способом - Yii не сможет отобразить связанные записи для быстрой загрузки, поэтому он не поддерживает это.Вы можете найти некоторое объяснение в этом ответе и связанной с ним проблеме на GitHub .
В зависимости от варианта использования вы можете попробовать два подхода, чтобы получить что-то похожее:
1.Два обычных отношения и метод получения для упрощения доступа
public function getSenderThreads() {
return $this->hasMany(MessageThread::className(), ['sender_id' => 'id']);
}
public function getRecipientThreads() {
return $this->hasMany(MessageThread::className(), ['recipient_id' => 'id']);
}
public function getMessageThreads() {
return array_merge($this->senderThreads, $this->recipientThreads);
}
Таким образом, у вас есть два отдельных отношения для потоков отправителя и получателя, так что вы можете использовать их напрямую с объединениями или активной загрузкой.Но у вас также есть getter, который будет возвращать результат как отношений, так что вы можете получить доступ ко всем потокам с помощью $model->messageThreads
.
2.Поддельные отношения
public function getMessageThreads()
{
$query = MessageThread::find()
->andWhere([
'or',
['sender_id' => $this->id],
['recipient_id' => $this->id],
]);
$query->multiple = true;
return $query;
}
Это не настоящие отношения.Вы не сможете использовать его с активной загрузкой или для объединений, но он будет извлекать все пользовательские потоки в одном запросе, и вы все равно сможете использовать его как обычное отношение активной записи - $model->getMessageThreads()
вернет ActiveQuery
и $model->messageThreads
массив моделей.
Почему orOnCondition()
не будет работать
orOnCondition()
и andOnCondition()
предназначены для дополнительныхON
условия, которые всегда будут добавлены к базовому условию отношения с использованием AND
.Поэтому, если у вас есть отношение, определенное следующим образом:
$this->hasMany(MessageThread::className(), ['sender_id' => 'id'])
->orOnCondition(['recipient_id' => new Expression('id')])
->orOnCondition(['shared' => 1]);
Это сгенерирует условие следующим образом:
sender_id = id AND (recipent_id = id OR shared = 1)
Как вы можете видеть, условия, определяемые orOnCondition()
, отделены от условия от отношенияопределены в hasMany()
, и они всегда объединяются с использованием AND
.