问题描述
我正在尝试使用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(/*...*/)
// ...
另请参见