Database 按活动记录yii2的计算字段列出的架次

Database 按活动记录yii2的计算字段列出的架次,database,activerecord,yii2,Database,Activerecord,Yii2,我在线程上有线程和消息 我想返回最后一个消息时间的所有线程,所以我在线程模型上添加了一个新字段,如下所示 public function fields() { $fields= ['idThread', 'idUser', 'title', 'unread', 'username','lastMesageTime']; return $fields; } 现在用这个方法我得到了lastMessageTime的计算值 public function getLa

我在线程上有线程和消息

我想返回最后一个消息时间的所有线程,所以我在线程模型上添加了一个新字段,如下所示

  public function fields()
  { 
    $fields= ['idThread', 'idUser', 'title', 'unread', 'username','lastMesageTime'];
    return $fields;
   }
现在用这个方法我得到了lastMessageTime的计算值

  public function getLastMessageTime()
   {
       return $this->hasMany(Messages::className(), ['idThread' => 'idThread'])
      ->select('time')->orderBy('time DESC')->limit(1)->scalar();
   }
在我的索引方法中使用如下活动记录

return Thread::find()->select('idThread, title, idUser')->all();
这是可行的,我使用正确的值获取lastMessageTime,但我想按顺序,这样我就可以获取具有最新lastMessageTime的线程第一个线程,我尝试了以下代码

  public function scopes() {
    return array(
        'byOrden' => array('order' => 'lastTimeMessage DESC'),
    );
}
有什么想法吗

编辑: 这个解决方法很有效,但我认为这不是一个好方法,因为我没有使用活动记录,所以像我在线程模型上定义的用户名这样的字段我必须再次获取它

 $query = (new \yii\db\Query());

    $query->select('*,  (SELECT max(time) as lastMessageTime  from messages where messages.idThread = thread.idThread ) lastMessageTime,
    (SELECT name from users where users.idUser = thread.idUser) as name ')
        ->from('threads')
        ->where(['idUser'=>$idUser])
        ->orderBy('lastMessageTime DESC');

    $rows = $query->all();
    return $rows;

您可以将额外字段定义为模型属性,然后重写find方法以加载这些字段的数据

class Thread extends \yii\db\ActiveRecord
{
    public $lastMessageTime;

    public static function find()
    {
        $q = parent::find()
            ->select('*')
            ->addSelect(
                 new \yii\db\Expression(
                     '(SELECT max(time) FROM messages WHERE messages.idThread = thread.idThread) AS lastMessageTime'
                 );
        return $q;
    }
}
然后,您可以像这样加载和订购模型:

$rows = Thread::find()->orderBy(['lastMessageTime' => SORT_DESC])->all();