laravel APi资源调用未定义的方法Illuminate\Database\Query\Builder :: mapInto()

Dav*_*eIt 14 api laravel laravel-5.5

我有一对一关系的Post和User模型,它运作良好:

//User.php

public function post(){
    return $this->hasOne(Post::class);
}


// Post.php

public function user() {
    return $this->belongsTo(User::class);
}
Run Code Online (Sandbox Code Playgroud)

现在我创建API资源:

php artisan make:resource Post
php artisan make:resource User
Run Code Online (Sandbox Code Playgroud)

我需要通过api调用返回所有帖子然后我设置我的路线:

//web.php: /resource/posts

Route::get('/resource/posts', function () {
    return PostResource::collection(Post::all());
});
Run Code Online (Sandbox Code Playgroud)

这是我的帖子资源类:

<?php

namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\Resource;
use App\Http\Resources\User as UserResource;

class Posts extends Resource
{
/**
 * Transform the resource into an array.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function toArray($request)
{
      return [
        'id' => $this->id,
        'title' => $this->title,
        'slug' => $this->slug,
        'bodys' => $this->body,
        'users' => UserResource::collection($this->user),
        'published' => $this->published,
        'created_at' => $this->created_at,
        'updated_at' => $this->updated_at,
    ];

}
}
Run Code Online (Sandbox Code Playgroud)

这是错误:

Call to undefined method Illuminate\Database\Query\Builder::mapInto()
Run Code Online (Sandbox Code Playgroud)

如果我删除:

'users' => UserResource::collection($this->user),
Run Code Online (Sandbox Code Playgroud)

它的工作,但我需要在我的api json中包含关系,我已阅读并遵循https://laravel.com/docs/5.5/collections的文档.

这是我的用户资源类:

```

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class User extends Resource
{
/**
 * Transform the resource into an array.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function toArray($request)
{
   return [
       'user_id' => $this->user_id,
       'name' => $this->name,
       'lastname' => $this->lastname,
       'email' => $this->email
   ];
}
}
Run Code Online (Sandbox Code Playgroud)

任何想法我错在哪里?

Mar*_*boc 50

问题是你使用的UserResource::collection($this->user)只有一个元素而不是集合,所以你可以用这样的方式替换它new UserResource($this->user):

return [
    'id' => $this->id,
    'title' => $this->title,
    'slug' => $this->slug,
    'bodys' => $this->body,
    'users' => new UserResource($this->user),
    'published' => $this->published,
    'created_at' => $this->created_at,
    'updated_at' => $this->updated_at,
];
Run Code Online (Sandbox Code Playgroud)


小智 13

这个问题是,你使用UserResource::collection($this->user)它意味着你有很多用户,但是你只有一个元素用于单个资源而不是一个集合,所以你可以将其替换为new UserResource($this->user)


run*_*ror 12

make在 Laravel 8.5.* 中,您可以在集合上使用静态方法来获得相同的结果。就像UserResource::make($this->user)


ell*_*iot 6

当您只有一个元素而不是集合时,请使用 new Resouce

return [
        'id' => $this->id,
        'name' => $this->name,
        'description' => $this->description,
        'user' => new UserResource($this->whenLoaded('user')),
];
Run Code Online (Sandbox Code Playgroud)

并尝试使用急切加载来获得更好的性能,而不仅仅是这个。使用方法whenLoaded并将关系名称放入()中。

当模型具有 hasMany 关系时,使用 Resource::collection。如果您的模型具有 hasOne 关系,请使用 Resource::make(Book::all())


小智 4

问题是您使用 UserResource::collection($this->user) 并且您只有一个来自数据库的元素,而不是集合列表。如果你像这样使用 new UserResource($this->user) 就可以解决这个问题:

<?php

namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\Resource;
use App\Http\Resources\User as UserResource;

class Posts extends Resource
{
/**
 * Transform the resource into an array.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function toArray($request)
{
      return [
        'id' => $this->id,
        'title' => $this->title,
        'slug' => $this->slug,
        'bodys' => $this->body,
        'users' => new UserResource($this->user),
        'published' => $this->published,
        'created_at' => $this->created_at,
        'updated_at' => $this->updated_at,
    ];

}
}
Run Code Online (Sandbox Code Playgroud)