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);
}),
];
}