【发布时间】:2023-03-25 18:18:01
【问题描述】:
假设我们有表 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。先getdog再getbreed,把数组结构和第一个一样,把结果做成json。
-
@ShaileshSingh 在问题的最底部,我举了一个你所描述的例子。我不想走这条路,因为这意味着我们必须遍历集合中的每个项目并重新格式化它,这是一个缓慢的过程