【发布时间】:2018-07-14 11:14:25
【问题描述】:
我有一个 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,
我猜我不能执行 'new TodoCollection($todos)' 其中 $todos 是一个结果数组。如何让我的 todoCollection 与数组一起使用?任何建议将不胜感激!
【问题讨论】:
-
你可以做的比这更简单
-
你是什么意思?
-
你可以在你的资源中传递集合对象,并像 laravel 文档所说的那样把它变成一个数组
-
如何在资源中做到这一点?从适配器返回一个数组不是为了更容易实现其他适配器吗?例如,如果我通过 API 适配器获取数据,那么如果资源需要一个数组,我就不需要将其转换为集合?
-
请看laravel.com/docs/5.5/eloquent-resources#introduction,上面写着`Laravel 的资源类允许你以富有表现力的方式轻松地将模型和模型集合转换为 JSON。`