在 Cakephp4 中加入查询只返回一个 table 数据
Joins Query in Cakephp4 only returning one table data
我正在尝试使用 CakePHP4 使用连接查询来获取评论,但是我得到的结果是简单的评论 table 数据。我怎样才能附加用户 table。
例如
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
class 中设置一个 BelongsTo
关联:
public function initialize(array $config): void
{
// ....
$this
->belongsTo('Users')
->setForeignKey('userId')
->setJoinType(\Cake\Database\Query::JOIN_TYPE_INNER);
}
理想情况下,您应该遵循命名约定并将外键字段命名为 user_id
,然后 CakePHP 将自动选择它,并且您不必使用非常规的字段名称进行配置(对于 BelongsTo
默认名称是关联名称的单数 lowercased/underscored 变体,附加 _id
)。
$reviews
->find()
->contain('Users')
->order(/*...*/)
// ...
结果看起来像这样:
{
"id": 1,
"userId": 1,
"rating": 4,
"review": "How are you",
"created": "2020-10-11T23:14:44+00:00",
"user": {
"id": 1,
"username": "Foo",
// ...
}
}
另见
我正在尝试使用 CakePHP4 使用连接查询来获取评论,但是我得到的结果是简单的评论 table 数据。我怎样才能附加用户 table。
例如
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
class 中设置一个 BelongsTo
关联:
public function initialize(array $config): void
{
// ....
$this
->belongsTo('Users')
->setForeignKey('userId')
->setJoinType(\Cake\Database\Query::JOIN_TYPE_INNER);
}
理想情况下,您应该遵循命名约定并将外键字段命名为 user_id
,然后 CakePHP 将自动选择它,并且您不必使用非常规的字段名称进行配置(对于 BelongsTo
默认名称是关联名称的单数 lowercased/underscored 变体,附加 _id
)。
$reviews
->find()
->contain('Users')
->order(/*...*/)
// ...
结果看起来像这样:
{
"id": 1,
"userId": 1,
"rating": 4,
"review": "How are you",
"created": "2020-10-11T23:14:44+00:00",
"user": {
"id": 1,
"username": "Foo",
// ...
}
}
另见