是否可以在分页中使用多个分形变换器?

时间:2014-06-24 17:24:26

标签: php laravel

我有一个控制器,可以返回所有喜欢的用户。这些喜欢可以来自Gig或Track。我已经使用多态关系来实现这一点。 Gigs和Tracks都有自己的Fractal变换器,可以完全独立工作。如果来自likes控制器的返回响应是包含其中的Gigs和Tracks对象的JSON响应,将会很有帮助。我希望你理解我的意思,但这是一个简短的例子。

响应看起来像这样:

{
"data": [
    {
        "id": 1,
        "user_id": 2,
        "name": "test",
        "genre": "test",
        "description": "",
        "venue": "test",
        "date": {
            "date": "-0001-11-30 00:00:00",
            "timezone_type": 3,
            "timezone": "UTC"
        },
        "lineup": "",
        "price": "0",
        "currency": "",
        "image": false,
        "attending_count": 0
    },
    {
        "id": 2,
        "user_id": 2,
        "name": "test",
        "genre": "test",
        "description": "",
        "URI" : "http://example.com/track",
    },

],
"meta": {
    "pagination": {
        "total": 2,
        "count": 2,
        "per_page": 50,
        "current_page": 1,
        "total_pages": 1,
        "links": []
    }
}
}

正如您所看到的,它们是响应的两个不同部分。我还想让它进一步嵌套数组,所以我有一个track: [和一个gig: [。但这是我稍后会看到的。

这是我到目前为止所拥有的。

    $user = User::find($userId);
    if (! $user){
        return $this->respondNotFound("This user could not be found.");
    }
    $arr = [];
    foreach ($user->likes()->get() as $like)
    {
        if($like->likeable_type == 'Gig'){
            $item = new Fractal\Resource\Item($like->likeable, new GigTransformer);
        }
        elseif($like->likeable_type == 'Track'){
            $item = new Fractal\Resource\Item($like->likeable, new TrackTransformer);
        }
        $arr[] = $item;
    }
    $paginator = Paginator::make($arr, count($arr), 50);
    return $paginator;

这将返回包含正确项目数但没有数据的分页。

如果您不理解我所说的任何内容,请发表评论。

非常感谢

2 个答案:

答案 0 :(得分:1)

经过一天的最佳时间,我已经弄清楚了,并且已经学到了很多关于物体等的知识。

这就是我所拥有的。

    $user = User::find($userId);
    if (! $user){
        return $this->respondNotFound("This user could not be found.");
    }
    $obj = new ArrayObject();
    $fractal = new Fractal\Manager();
    $fractal->setSerializer(new Fractal\Serializer\JsonApiSerializer());
    foreach ($user->likes()->get() as $like)
    {
        if($like->likeable_type == 'Gig'){
            $item = new Fractal\Resource\Item($like->likeable, new GigTransformer, 'gig');
        }
        elseif($like->likeable_type == 'Track'){
            $item = new Fractal\Resource\Item($like->likeable, new TrackTransformer, 'track');
        }
        $obj->append($fractal->createData($item)->toArray());
    }
    $paginator = Paginator::make((array) $obj, $obj->count(), 50);
    $response = [
        'likes' => (array) $obj,
        'meta' => [
            'pagination' => [
                'total' => $paginator->getTotal(),
                'count' => $paginator->count(),
                'per_page' => $paginator->getPerPage(),
                'current_page' => $paginator->getCurrentPage(),
                'total_pages' => $paginator->getLastPage(),
                'links' => $paginator->links(),
            ],
        ]
    ];
    return ($this->respond($response));

我认为你可以很容易地看到这里发生了什么。

我使用了ArrayObject,这样我就可以保留Fractal Item对象,而不会将其隐藏到数组中并仍然使用数组函数。分形项目附加到ArrayObject,然后进行分页。我想以特定的方式显示分页,likes包装所有用户数据,meta包装分页数据。这个respond()方法只是我在整个控制器中用来以JSON格式响应的方法。

希望这可以帮助任何想要做类似事情的人。我喜欢Laravel。

答案 1 :(得分:0)

您可以将它放到它所属的转运者级别:

use League\Fractal\Resource\Item;

public function transform($item)
{
    $transformer_class = null;
    switch($item->type)
    {
        case "gig" :
            $transformer_class = new TransporterGig();
            break;
        case "track":
        default:
            $transformer_class = new TransporterTrack();
            break;
    }
    $resource = new Item($item, $transformer_class);
    return $this->currentScope->getManager()->createData($resource)->toArray()["data"];
}