使用数组而不是模型

时间:2018-02-04 13:02:18

标签: laravel rest

我有一个API,它使用API​​资源和资源集合来正确格式化JSON响应。为了将我的控制器与模型分离,我使用适配器来查询底层模型。我希望将适配器返回值作为数组而不是Eloquent模型传递,以确保任何未来适配器在返回数据结构方面更容易。要创建数组返回值,我使用 - > toArray()将我的适配器Eloquent结果序列化。

我有2个API资源来正确格式化这些结果,对于我拥有的单个资源:

使用Illuminate \ Http \ Resources \ Json \ Resource;

class Todo extends Resource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return $this->resource;
    }
}

对于资源集合,我有:

使用Illuminate \ Http \ Resources \ Json \ ResourceCollection;

class TodoCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => $this->collection
                          ->map
                          ->toArray($request)
                          ->all()
        ];
    }
}

当我从控制器返回单个资源时:

use App\Http\Resources\Todo;

public function show($id)
{
    return new Todo($this->todoAdapter->findById($id));
}

并将适配器查询为:

public function findById(int $id){
        return TodoModel::findOrFail($id)
                ->toArray();
}

这可以按预期工作。当我尝试传递模型集合的数组时,问题就出现了。

public function index(Request $request)
{
    $todos = $this->todoAdapter->getAllForUserId(Auth::id(), 'created_by', 'desc', self::DEFAULT_PAGINATE);
    return new TodoCollection($todos);
}

并将适配器查询为:

public function getAllForUserId(int $userId, string $sortField, string $sortDir, int $pageSize = self::DEFAULT_PAGINATE)
{
        return Todo::BelongsUser($userId)
                                    ->orderBy($sortField, $sortDir)
                                    ->paginate($pageSize)
                                    ->toArray();
}

我收到以下错误:

"message": "Call to a member function first() on array",
    "exception": "Symfony\\Component\\Debug\\Exception\\FatalThrowableError",
    "file": "/home/vagrant/code/public/umotif/vendor/laravel/framework/src/Illuminate/Http/Resources/CollectsResources.php",
    "line": 24,

我猜我不能做新的TodoCollection($ todos)'其中$ todos是一个结果数组。我如何让我的todoCollection与数组一起工作?任何建议将不胜感激!

2 个答案:

答案 0 :(得分:0)

你的集合toArray试图做太多:

$this->collection
         ->map
         ->toArray($request)
         ->all()

直接致电$this->collection->toArray()

答案 1 :(得分:0)

只是为了更新这个。最后,我发现从结果数组创建一个集合并将其传递给资源集合构造函数,虽然我必须在资源集合中为链接和元素等添加显式映射。