Home > other >  Add foreach for toarray to a JsonResource in Laravel REST API
Add foreach for toarray to a JsonResource in Laravel REST API

Time:07-05

I have a collection of genres for every movie and I wanna display every one that each movie has in the api request. Here's the resource:

    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'status' => $this->status,
            'image_path' => url()->to('/images/' .$this->image_path),
            'genres' => ''
        ];
    }

I believe I need to access genres in Movie model and use foreach in toarray function but how exactly it should be done? Here's my migrations:

    public function up()
    {
        Schema::create('genres', function (Blueprint $table) {
            $table->id();
            $table->string('name');
        });
    }

    public function up()
    {
        Schema::create('movies', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->integer('status')->nullable()->default(0);
            $table->string('image_path')->default('default.png');
        });
    }

    public function up()
    {
        Schema::create('genre_movie', function (Blueprint $table) {
            $table->foreignId('genre_id')->constrained()->cascadeOnDelete();
            $table->foreignId('movie_id')->constrained()->cascadeOnDelete();
        });
    }

Movie model:

class Movie extends Model
{
    use HasFactory;

    public $timestamps = false;
    protected $fillable = ['name', 'status', 'image_path'];

    public function genres()
    {
        return $this->belongsToMany(Genre::class, 'genre_movie');
    }
}

Genre model:

class Genre extends Model
{
    use HasFactory;

    public $timestamps = false;
    protected $fillable = ['name'];

    public function movies()
    {
        return $this->belongsToMany(Movie::class, 'genre_movie');
    }
}

Function in controller:

    public function index()
    {
        return MovieResource::collection(Movie::paginate());
    }

CodePudding user response:

Create a genre resouce.

class GenreResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'name' => $this->name,
        ];
    }
}

Load it in the controller using with().

public function index()
{
    $movies = Movie::with('genres')->paginate();

    return MovieResource::collection();
}

Add it to the MovieResource, use whenLoaded() and a closure, so you don't have to show it, if it is not loaded.

public function toArray($request)
{
    return [
        ...
        'genres' => $this->whenLoaded('genres', function () {
            return GenreResource::collection($this->genres);
        }),
    ];
}
  • Related