gpt4 book ai didi

php - Laravel 5.6 中嵌套关系的展平结果

转载 作者:行者123 更新时间:2023-12-05 03:05:02 25 4
gpt4 key购买 nike

我有一个具有以下模型的 laravel 应用程序

Location (hasOne: Device)  : [id, device_id, lat, lng] 
Device (hasMany: Location) : [id, name]

我需要获取给定设备的最新位置。假设我有一组设备 ID。

[1, 2, 3]

我正在尝试制作一个 api,它应该对请求给出一个简单的响应。显然,响应应该是这样的。

[
{
"device_id": "1",
"name": "A",
"lat":"8.311",
"lng":"11.1111"
},
{
"device_id": "2",
"name": "B",
"lat":"8.1111",
"lng":"88.1111"
},
{
"device_id": "3",
"name": "C",
"lat":"5.1111",
"lng":"25.1111"
}
]

我尝试了很多方法来找到一个有效的解决方案来得到正确的答案。到目前为止,我能想到的最佳解决方案是使用 device_id 直接从 Location 表中获取最新位置。所以我试过了。

Location::whereIn('device_id', [1, 2, 3])->get()

它给出了给定设备的所有位置条目。但我只想要每个设备的最新位置条目。所以我试过了。

Location::whereIn('device_id', [1, 2])->latest()->first()->get()

这显然为我提供了每个设备的多个位置。我不确定如何解决这个问题。

>>> Location::whereIn('device_id', [1, 2])->get()
=> Illuminate\Database\Eloquent\Collection {#2883
all: [
App\Location {#2895
id: 1,
device_id: 1,
lat: "39",
lng: "53",
extras: "JCRskRtaBJ",
delete_flag: 0,
created_at: "2018-07-25 12:11:21",
updated_at: "2018-07-25 12:11:21",
},
App\Location {#2903
id: 3,
device_id: 1,
lat: "73",
lng: "23",
extras: "0cOy8rne9S",
delete_flag: 0,
created_at: "2018-07-25 12:11:21",
updated_at: "2018-07-25 12:11:21",
},
App\Location {#2894
id: 5,
device_id: 2,
lat: "55",
lng: "28",
extras: "rT18VZxA7i",
delete_flag: 0,
created_at: "2018-07-25 12:11:21",
updated_at: "2018-07-25 12:11:21",
},
App\Location {#2885
id: 7,
device_id: 1,
lat: "58",
lng: "74",
extras: "TAbM4x53iH",
delete_flag: 0,
created_at: "2018-07-25 12:11:21",
updated_at: "2018-07-25 12:11:21",
},
App\Location {#2900
id: 8,
device_id: 1,
lat: "47",
lng: "7",
extras: "yhr4sbUs2R",
delete_flag: 0,
created_at: "2018-07-25 12:11:21",
updated_at: "2018-07-25 12:11:21",
},
App\Location {#2882
id: 9,
device_id: 2,
lat: "27",
lng: "60",
extras: "NqRPvaqosG",
delete_flag: 0,
created_at: "2018-07-25 12:11:21",
updated_at: "2018-07-25 12:11:21",
},
App\Location {#2915
id: 10,
device_id: 1,
lat: "35",
lng: "37",
extras: "6e7yHT4qP3",
delete_flag: 0,
created_at: "2018-07-25 12:11:21",
updated_at: "2018-07-25 12:11:21",
},
],
}

我正在寻找一个仅从位置类返回 latlng 并将其附加为属性的查询,这样我就可以得到一个简单的 json 响应。无论如何有可能做到吗?

最佳答案

你可以使用 Eloquent: API Resources 得到你想要的:

首先在 Device 模型中创建一个新关系,即使 hasMany 是它们之间的真正关系,您也可以将 hasOnelatest() 获取最后一个位置:

public function lastLocation()
{
return $this->hasOne('App\Location')->latest();
}

然后你必须创建一个设备资源:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class Device extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return [
'device_id' => $this->id,
'name' => $this->name,
'lat' => $this->lastLocation->lat,
'lng' => $this->lastLocation->lng,
];
}
}

最后在 Controller 中你可以这样做:

use App\Device;
use App\Http\Resources\Device as DeviceResource;

function YourMethod() {
$devices = Device::with('lastLocation')
->whereIn([1, 2, 3])
->get();
return DeviceResource::collection($devices);
}

文档中提到的另一件事:

By default, your outer-most resource is wrapped in a data key when the resource response is converted to JSON. So, for example, a typical resource collection response looks like the following:

{
"data": [
{
"id": 1,
"name": "Eladio Schroeder Sr.",
"email": "therese28@example.com",
},
{
"id": 2,
"name": "Liliana Mayert",
"email": "evandervort@example.com",
}
]
}

删除数据包装器:

If you would like to disable the wrapping of the outer-most resource, you may use the withoutWrapping method on the base resource class. Typically, you should call this method from your AppServiceProvider or another service provider that is loaded on every request to your application :

public function boot()
{
Resource::withoutWrapping();
}

关于php - Laravel 5.6 中嵌套关系的展平结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51522712/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com