Php 用查询模拟即时加载

Php 用查询模拟即时加载,php,laravel,laravel-5,Php,Laravel,Laravel 5,假设我们有带有相应型号的表狗和品种: class Dog extends Model { protected $table = 'dogs'; protected $fillable = [ 'name', 'breed_id' ]; protected $hidden = [ 'breed_id' ]; public function breed() { return $this->belongsTo(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');
    }
}

我们可以像这样快速加载和访问该品种:

$dogs = Dog::with('breed')->all();
如果我们有一个API函数返回这个狗的集合,默认情况下它将把它们格式化为JSON,每个狗对象将有一个“繁殖”对象:

{"dogs":[
    {
      "id": 1,
      "name": "Rover",
      "breed": {
                 "id": 1,
                 "name": "Golden Retriever"
               }
    }
    //etc
现在让我们假设我们需要使用原始查询加载狗(这是一个简单的示例,请假装我们使用原始查询有一个很好的理由)。我们可以使用连接获取品种名称:

$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"
    }
有没有办法让原始查询结果的格式与雄辩的模型结果相同,而不必这样做?

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函数是使用Elounce with eager loading,还是使用原始查询。

即使使用具有非常好的JSON支持的数据库,准确返回您想要的结果也不太可行

AFAIK MySQL不支持数组,但在Postgres中,您可以选择数组中的品种信息,但即使这样,您也不能为数组的元素设置关键帧

您可以将所有内容选择为JSON:

-- Postgres Example
SELECT row_to_json(row(dogs.*, ARRAY[breeds.name, breeds.id])) FROM ...

但是,与仅在代码中而不是在SQL中实现所需的功能相比,键入值要费劲得多。

我认为您需要创建类似于第一个数组的数组,以便以预期的方式转换和返回json。首先得到狗,然后得到品种,使数组结构与第一个相同,并得出结果。@ShaileshSingh在问题的最底部,我给出了一个你描述的例子。我不想走这条路,因为这意味着我们必须迭代集合中的每个项并重新格式化,这是一个缓慢的过程
-- Postgres Example
SELECT row_to_json(row(dogs.*, ARRAY[breeds.name, breeds.id])) FROM ...