Laravel + fractal“深度”嵌套包括

时间:2017-03-02 00:40:42

标签: php web-services laravel-5

我使用分形(fractal.thephpleague.com)与Laravel(laravel.com)开发API。顺便说一下,这是一个了不起的图书馆。

在某些Web服务中,我需要返回几个嵌套模型的信息,这些模型有3个级别。也就是说,我有一个调查模型,它有很多调查项目,而且每个模型都有很多调查项目结果(每个用户)。好吧,我需要所有这些数据,分类,即:

"surveys": [
    {
        "id": 1,
        ...,
        "items": [
            {
                "id": 14,
                ...,
                "results": [
                    {
                        "id": 45,
                        ...
                    }, 
                    {
                        ...
                    }
                ]
            }, 
            {
                ...
            } 
        ]
    },
    {
       ...
    }
 }

使用变压器和包含,我可以毫无问题地获得调查和调查项目信息,但我还需要调查项目结果...... 也就是说,我需要像 2级“嵌套”包含的内容,以获取第三级别的信息。

迄今为止我的最佳方法(仅返回两个级别:调查和调查项目)。在我的控制器中:

return fractal() -> transform(
     Survey::where(...),
     new SurveyTransformer()
) -> include(['SurveyItems']) -> respond();

非常感谢任何帮助。 提前谢谢。

1 个答案:

答案 0 :(得分:2)

这是我通常做的事情

调查变压器

<?php
namespace App\Transformers;

use League\Fractal;
use App\Survey;

class SurveyTransformer extends Fractal\TransformerAbstract
{
    /**
     * List of resources possible to include
     *
     * @var array
     */
    protected $availableIncludes = [
        'items'
    ];

    public function transform(Survey $survey)
    {
        return [
            'id'    => (int) $user->id,
        ];
    }


    /**
     * Include Items
     *
     * @param App\Survey $survey
     * @return League\Fractal\CollectionResource
     */
    public function includeItems(Survey $survey)
    {
        $items = $survey->items;
        if (!is_null($items)) {
            return $this->collection($items, new ItemTransformer);
        }
        return;
    }
}

项目转换器

<?php
namespace App\Transformers;

use League\Fractal;
use App\Item;

class ItemTransformer extends Fractal\TransformerAbstract
{
    /**
     * List of resources possible to include
     *
     * @var array
     */
    protected $availableIncludes = [
        'results'
    ];

    public function transform(Item $item)
    {
        return [
            'id'    => (int) $user->id,
        ];
    }


    /**
     * Include results
     *
     * @param App\Item $item
     * @return League\Fractal\CollectionResource
     */
    public function includeResults(Item $item)
    {
        $results = $item->results;
        if (!is_null($results)) {
            return $this->collection($results, new ResultTransformer);
        }
        return;
    }
}

在我的基本控制器上

    /**
     * get fractal tranformed data
     * @param $resource
    */
    protected function fractalResponse($resource, array $includes = [])
    {
        $manager = new Manager();
        $manager->setSerializer(new DataArraySerializer()); //or what ever you like

        if (sizeof($includes) == 0) {
            $data = $manager->createData($resource)
                ->toArray();
        } else {
            $manager->parseIncludes($includes);
            $data = $manager->createData($resource)
                ->toArray();
        }
        return $data;
    }

然后

$resource = new \League\Fractal\Resource\Collection($survies, new SurveyTransformer);
$response_data = $this->fractalResponse($resource, ['items.results'])