在Cakephp4中加入查询仅返回一个表数据

问题描述

我正在尝试使用CakePHP4的联接查询获取评论,但是我得到的结果是简单的Reviews表数据。我如何也可以附加用户表。

例如

public function getReviews()
{
    $this->request->allowMethod(['get']);
    
    //$authenticator = new JWTController();
    //$data        = $authenticator->requestAuthorization();

    $offset = 1;//$data['offset']; 
    
    $reviews = $this->getTableLocator()->get('Reviews');
    $result = $reviews
        ->find('all')
        ->join([
            'Users'=>  [
                'table'      => 'users','type'       => 'INNER','conditions' => 'Users.id = Reviews.userId',]
        ])
        ->order(['Reviews.created' => 'DESC'])
        ->limit(25)
        ->page($offset)->toArray();
            
    $this->jsonOutput(array(
        'error' => false,'limit' => 25,'data'  => $result
    ));
}
{
    "id": 1,"userId": 1,"rating": 4,"review": "How are you","created": "2020-10-11T23:14:44+00:00"
}

解决方法

检查生成的SQL!联接某物首先将要做的就是创建联接。如果要从该联接中获取任何数据,则必须通过选择相应的字段将其明确告知查询构建器:

$reviews
    ->find()
    // select all fields of the reviews table
    ->select($reviews)
    // select specific fields from the join
    ->select(['Users.username','Users.email',/* ... */])
    ->join(/* ... */)
    // ...

结果看起来像这样(您可能想为连接使用不同的别名,因为Users很奇怪,至少应该是单数):

{
    "id": 1,"userId": 1,"rating": 4,"review": "How are you","created": "2020-10-11T23:14:44+00:00","Users": {
        "username": "Foo","email": "foo@example.com",// ...
    }
}

但是,您可能应该改为进行关联,然后使用contain(),这样您就不必一遍又一遍地重复自己。在您的ReviewsTable类中,建立一个BelongsTo关联:

public function initialize(array $config): void
{
    // ....

    $this
        ->belongsTo('Users')
        ->setForeignKey('userId')
        ->setJoinType(\Cake\Database\Query::JOIN_TYPE_INNER);
}

理想情况下,您应该遵循命名约定,而是将外键字段命名为user_id,然后CakePHP会自动选择它,并且您不必使用非常规字段名称进行配置(对于{{1 }}默认名称是关联名称的单数形式,小写/加下划线,并附加了BelongsTo

_id

结果看起来像这样:

$reviews
    ->find()
    ->contain('Users')
    ->order(/*...*/)
    // ...

另请参见