如何正确地将排序模型从我的控制器发送到 Laravel API 资源集合?

Posted

技术标签:

【中文标题】如何正确地将排序模型从我的控制器发送到 Laravel API 资源集合?【英文标题】:How to properly send a sorted model from my controller to the Laravel API Resource collection? 【发布时间】:2020-07-20 19:08:12 【问题描述】:

这是我的控制器:

    public function branchesNearby($lat, $lng)


    $branches = Branch::all();

    //Calculate distance between each branch and client
    //Radius of earth is 6371 KM so multiply the result with radius of earth 6371*pi/180
    foreach ($branches as $branch)
    $branch['distance'] = sqrt(pow(($branch->lat - $lat), 2) + pow(($branch->lng - $lng), 2)) * 108;
    

    //Sort by nearest first
    $sortedBranches = $branches->sortBy('distance');

    return BranchResource::collection($sortedBranches);


你可以看到我创建了一个额外的属性来计算用户位置和分支位置之间的距离。然后,我按距离对分支模型进行排序。但是,我得到的 api 响应是: API response

你可以看到它是一个对象。我不需要键“2”、“0”和“1”。我需要删除这个额外的包装,我需要它是一个像这样的对象数组: Correct API but without sorting 当然,是排序导致它成为一个对象?我尝试了许多其他方法,其中之一是:

$sortedBranches = $collection->sortBy('distance');
$final = $sortedBranches->values()->toJson(); 

并将这个 $final 发送到资源集合。这给了我错误:“在文件 api 资源中的字符串上调用成员函数 first()”。这一定是件小事,但我真的需要帮助。

更新: 我之前没有发布我的资源,是这样的:

    public function toArray($request)
    

        return [
            'id' => $this->id,
            'shop' => $this->shop->name,
            'shop_image' => asset('api/images/' . $this->shop->image_file),
            'lat' => $this->lat,
            'lng' => $this->lng,
            'shop_logo' => asset('api/images/' . $this->shop->logo_file),
            'distance' => $this->distance . " KM"

        ];

如果我使用我得到的错误:

$sortedBranches = $branches->sortBy('distance')->values()->all();
   return BranchResource::collection($sortedBranches);

是: The error

更新 3:

如果我不调用资源集合并像这样简单地输出 $sortedBranches:

return response()->json($sortedBranches, 200);

这里,api响应的格式正确但数据不正确。这是它的外观: $sortedBranches

有没有一种方法可以操纵 $sortedBranches 并像使用 BranchResource 一样显示输出?

【问题讨论】:

我相信你需要这样做:$sortedBranches = $branches->sortBy('distance')->values()->all(); 然后你的 json 应该看起来像你的第二张图片:) 除非问题是由你的最后一个包装器引起的:BranchResource::collection($sortedBranches);。试一试吧:) 距离值是否也包括“公里”?因为你的控制器没有显示公里的东西。您将按包含“km”的距离进行排序。 您应该通过这些值(lat、lng)查询数据库——而不是全部获取然后对其中的一些进行分类。 @RobBiermann 感谢您的回复。我之前也试过这个!这给了我同样的错误。 “在文件 api 资源中的字符串上调用成员函数 first()”。 @JawadChughtai 好的,该错误是指向您已发布的代码,还是指您尚未发布的一段代码? 【参考方案1】:

根据我们的故障排除,最终的解决方案应该是:

return BranchResource::collection($sortedBranches)->values()->all();

当您将集合传递给BranchResource 类的collect 方法时,它会重新创建集合。 Laravel 看到您直接从控制器返回一个(集合)对象,并通过将其转换为 json 进行干预(我相信这是默认设置)。如果生成的 json 没有按照你想要的方式转换,你需要修改这个集合。因此我们需要修改BranchResource::collection() 集合,而不是$sortedBranches 集合。

编辑:

将collect方法修改为collection;

【讨论】:

小编辑:return BranchResource::collect($sortedBranches)->values()->all(); 实际上是return BranchResource::collection($sortedBranches)->values()->all(); 我错了输入错误。再次感谢@Rob Biermann 感谢您的反馈,我修改了答案:) @JawadChughtai 你能投票/标记答案吗? :D 那么我们是偶数;) 完成。我不能投票,因为我的声望少于 15,但我接受了它作为答案:)

以上是关于如何正确地将排序模型从我的控制器发送到 Laravel API 资源集合?的主要内容,如果未能解决你的问题,请参考以下文章

如何将模型的(json)值发送到视图控制器?

如何正确地将 JSON 元数据值发送到 Woocommerce API

如何正确地将数据从 vue 组件发布到 laravel 控制器

Django - 如何正确地将列表从模板发送到 AJAX 以查看?

如何将 json 数据从我的 jsp 页面发送到 spring rest 控制器

如何使用 jquery ajax 正确地将 json 对象传递给烧瓶服务器