我有一张桌子0.9
:
message_thread
我想在我的id
sender_id
recipient_id
模型中声明一个关系,该关系将按如下方式获取所有消息线程:
User
我尝试了以下方法:
SELECT *
FROM message_thread
WHERE sender_id = {user.id}
OR recipent_id = {user.id}
但是它会生成一个public function getMessageThreads()
{
return $this->hasMany(MessageThread::className(), ['sender_id' => 'id'])
->orWhere(['recipient_id' => 'id']);
}
查询。有谁知道该怎么做?
答案 0 :(得分:2)
您不能以这种方式创建常规关系-Yii将无法映射相关记录以进行紧急加载,因此不支持此操作。您可以在this answer和相关的issue on GitHub中找到一些解释。
根据用例,您可以尝试两种方法来获得相似的结果:
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
访问所有线程。
public function getMessageThreads()
{
$query = MessageThread::find()
->andWhere([
'or',
['sender_id' => $this->id],
['recipient_id' => $this->id],
]);
$query->multiple = true;
return $query;
}
这不是真实的关系。您将无法在紧急加载或联接中使用它,但它将在一个查询中获取所有用户线程,并且仍将其用作常规活动记录关系-$model->getMessageThreads()
将返回{{1 }}和ActiveQuery
模型数组。
$model->messageThreads
不起作用 orOnCondition()
和andOnCondition()
用于其他orOnCondition()
条件,这些条件将始终使用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()
进行连接。
答案 1 :(得分:0)
对于此查询
SELECT *
FROM message_thread
WHERE sender_id = {user.id}
OR recipent_id = {user.id}
您可以使用这些
$query = (new \yii\db\Query)->from("message_thread")
$query->orFilterWhere(['sender_id'=>$user_id])->orFilterWhere(['recipent_id '=>$user_id]);