Laravel API资源响应分组

tkqqtvp1  于 2022-11-26  发布在  其他
关注(0)|答案(2)|浏览(128)

UPD:已解决。我猜(检查以下内容)

我尝试使用Laravel Resources按特定列对API响应进行分组
就像这样

{
   "data":{
      "1":[ <=== (!!) To have this groups
         {
            "id":63,
            "eve_id":95924195,
            "name":"John",
            "group":1, <== (!!!) from this column
            "is_active":1,
            "is_editable":1,
            "created_at":"2018-11-08 05:26:20",
            "updated_at":"2018-11-08 05:26:20"
         },
         {
            "id":64,
            "eve_id":95824961,
            "name":"Doe",
            "group":1,
            "is_active":1,
            "is_editable":1,
            "created_at":"2018-11-08 05:41:10",
            "updated_at":"2018-11-08 05:41:10"
         }
      ]
   }
}

我的资源示例

class SomeResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'group' => $this->group,
            'is_active' => $this->is_active,
            'is_editable' => $this->is_editable,
            'created_at' => (string) $this->created_at,
        ];
    }
}

我收藏示例:

class SomeCollection extends ResourceCollection
{
    public $collects = 'App\Http\Resources\SomeResource';

    public function toArray($request)
    {
        return [
            'data' => $this->collection,
        ];
    }
}

使用基本的雄辩方法

Some::where('is_active', '1')->get()->groupBy('group');
return ['entries' => $entries];

如果我能传递这些条目并在ResourceCollection中迭代它们,我至少不能解决问题

  • 谢谢-谢谢

UPD:好的,通过创建新的资源示例SomeGroupCollection和分组,问题已得到解决,分组来自基本的雄辩方法

$entries = Some::where('is_active', '1')->get()->groupBy('group');
    return new SomeGroupCollection($entries);

某个组集合

class SomeGroupCollection extends ResourceCollection
{

    public $collects = 'App\Http\Resources\SomeCollection';

    public function toArray($request)
    {
        return [
            'entries' => $this->collection
        ];
    }
}

某个集合

class SomeCollection extends ResourceCollection
{

    public $collects = 'App\Http\Resources\SomeResource';

    public function toArray($request)
    { 
        return [
             $this->collection,
        ];
    }
}

某些资源

class SomeResource extends JsonResource
{

    public function toArray($request)
    {

        return [
            'id' => $this->id,
            'name' => $this->name,
            'group' => $this->group,
            'is_active' => $this->is_active,
            'is_editable' => $this->is_editable,
            'created_at' => (string) $this->created_at,
        ];
    }
}
e4yzc0pl

e4yzc0pl1#

这对我在Laravel 8中起作用,但我怀疑它在以前的版本中也会起作用。

SomeResource::collection($models)->groupBy('group');

但是没有data密钥。

rbl8hiat

rbl8hiat2#

虽然您可以直接使用groupBy on result of collection方法,但是您将丢失有关分页的任何元数据以及使用数据键的任何 Package 。
我通过创建一个新的类来解决这个问题,这个类是从现有的JsonResource类扩展而来的。基本上,它在过滤资源后注入groupBy逻辑。只需在App目录中创建GroupedResources.php和GroupedResourceCollection.php,并在其中输入以下代码。

应用程序\分组资源集合

<?php

namespace App;

use Illuminate\Http\Resources\Json\AnonymousResourceCollection;

class GroupedResourceCollection extends AnonymousResourceCollection
{
    /**
     * Resolve the resource to an array.
     *
     * @param  \Illuminate\Http\Request|null  $request
     * @return array
     */
    public function resolve($request = null): array
    {
        return isset($this->groupBy)
            ? collect(parent::resolve($request))->groupBy($this->groupBy, $this->preserveKeys ?? false)->all()
            : parent::resolve($request);
    }
}

从上面的代码中可以看到,parent::resolve($request)方法返回过滤后的数据,因此它是对数据进行分组的理想位置。

应用程序\分组资源

<?php

namespace App;

use Illuminate\Http\Resources\Json\JsonResource;

/**
 * @property boolean $preserveKeys
 * @property array $groupBy
 */
class GroupedResource extends JsonResource
{
    /**
     * Create a new grouped resource collection.
     *
     * @param  mixed  $resource
     * @return \App\GroupedResourceCollection
     */
    public static function collection($resource): GroupedResourceCollection
    {
        return tap(new GroupedResourceCollection($resource, static::class), function ($collection) {
            if (property_exists(static::class, 'preserveKeys')) {
                $collection->preserveKeys = (new static([]))->preserveKeys === true;
            }
            if (property_exists(static::class, 'groupBy')) {
                $collection->groupBy = (new static([]))->groupBy;
            }
        });
    }
}

JsonResource类返回AnonymousResourceCollection类的示例,因此要使用GroupedResourceCollection类并示例化该类上的groupBy属性,我们必须修改JsonResource类的签名。我们可以通过创建一个名为GroupedResource的新类来完成此操作,该新类从JsonResource类扩展而来,如上所示。
现在您可以像往常一样创建资源来使用它,但这次不是从JsonResource类扩展它,而是从GroupedResource类扩展它。您可以分配groupBy变量来对它进行分组。

应用程序\Http\资源\用户资源

<?php

namespace App\Http\Resources;

use App\GroupedResource;

class UserResource extends GroupedResource
{
    protected array $groupBy = ['country', 'state'];

    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'address' => $this->address,
            'state' => $this->state,
            'country' => $this->country
        ];
    }
}

您将获得集合分组的所有好处,因此您可以创建groupBy数组,就像您可以对集合groupBy方法所做的那样,如下所示。

相关问题