假设我们有表 dog
和 breed
以及相应的模型:
class Dog extends Model {
protected $table = 'dogs';
protected $fillable = [
'name', 'breed_id'
];
protected $hidden = [ 'breed_id' ];
public function breed() {
return $this->belongsTo(Breed::class, 'breed_id');
}
}
和
class Breed extends Model {
protected $table = 'breeds';
protected $fillable = [
'name'
];
}
我们可以像这样预先加载和访问品种:
$dogs = Dog::with('breed')->all();
如果我们有一个 API 函数返回这个狗的集合,默认情况下它会将它们格式化为 JSON,并且每个狗对象都有一个“品种”对象:
{"dogs":[
{
"id": 1,
"name": "Rover",
"breed": {
"id": 1,
"name": "Golden Retriever"
}
}
//etc
现在假设我们需要使用原始查询加载狗(这是一个简单的示例,请假装我们使用原始查询是有充分理由的)。我们可以使用 JOIN 获取品种名称:
$query = "SELECT dogs.*, breeds.name AS breed_name
FROM dogs
JOIN breeds ON dogs.breed_id = breeds.id";
$dogs = DB::select(DB::raw($query));
但是,如果我们将其作为 JSON 返回,它将具有不同的结构:
{"dogs":[
{
"id": 1,
"name": "Rover",
"breed_id": 1,
"breed_name": "Golden Retriever"
}
有没有什么办法可以让我们的原始查询结果具有与 Eloquent 模型结果相同的格式,而不必这样做?
foreach ($dogs as $dog) {
$dog['breed'] = array(
'id' = $dog['breed_id'],
'name' => $dog['breed_name']
);
unset($dog['breed_id']);
unset($dog['breed_name']);
}
return $dogs;
我问是因为我不希望客户端应用程序必须以两种不同的方式解析结果,具体取决于特定的 API 函数是使用 Eloquent 和预加载,还是使用原始查询。
最佳答案
即使使用具有非常好的 JSON 支持的数据库,准确返回您想要的内容也不是那么可行。
AFAIK MySQL 不支持数组,但在 Postgres 中您可以选择数组中的品种信息,但即便如此您也无法键入数组的元素。
您可以选择所有内容作为 JSON:
-- Postgres Example
SELECT row_to_json(row(dogs.*, ARRAY[breeds.name, breeds.id])) FROM ...
但同样,键入值比仅在代码中而不是在 SQL 中实现所需的功能要费力得多。
关于php - 使用查询模拟预加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41884547/