Meaulnes's avatar

How to return a belongsTo relationship as a Resource

I have a person resource like this

class PersonResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            "id"=> $this->id,
            'firstName'=>$this->firstName,
            'lastName'=>$this->lastName,
            'fullName'=>$this->firstName.' '.$this->lastName,//for convenience in the front end
            'email'=>$this->email,
            'phone'=>$this->phone,
            'memberSince'=>$this->memberSince,
            'memberLastYear'=>$this->memberLastYear
        ];
    }
}

in this , the fullName is not part of the original Person model and not saved in the database.

There is a relationship one to many with Participation model like this

in the Person model

 /**
     * Get all of the person's participations.
     */
    public function participations(): HasMany
    {
        return $this->hasMany(Participation::class);
    }

in the Participation model

 /**
     * Get the person associated with the participation.
     */
    public function person():BelongsTo
    {
        return $this->belongsTo(Person::class);

    }

I can get all the person with the index action of a PersonController

class PersonController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        //
        return   PersonResource::collection(Person::orderBy('lastName')->get());
    }

It returns the collection of PersonResource and I have the fullName property in them.

So far so good!

After that I have an Event model that has a hasManyThrough relationship with the Person model . An Event has many Participation but a Participation belongsTo one Person

When I want to return the Person(s) that belongsTo the Event I do this

class EventPersonController extends Controller
{
    public function index(Event $event)
{
    $participations=ParticipationResource::collection($event->participations);
    $result=[];
    foreach($participations as $p){
        array_push($result,$p->person);
    }
    return response()->json(['data'=>array_unique($result)]);
{

}
}}

I get the array of Person (s) but in this case the fullName is not present. How to return indivual PersonResource instead of Person ?

0 likes
2 replies
JohnnyBigodes's avatar

Have you tried getting the model data with the relationship?

class PersonController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        //
        return   PersonResource::collection(Person::orderBy('lastName')->with('participations')->get());
    }

The in the Resource you could just get whatever Attribute you want from participations:

class PersonResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            "id"=> $this->id,
            'firstName'=>$this->firstName,
            'lastName'=>$this->lastName,
            'fullName'=>$this->participations->fullname // Whatever field you need from "participations"
            'email'=>$this->email,
            'phone'=>$this->phone,
            'memberSince'=>$this->memberSince,
            'memberLastYear'=>$this->memberLastYear
        ];
    }
}
Meaulnes's avatar

Thank you for your answer. I am afraid this could not work (but I must be careful here as I am not an expert) because the Participation has no fullname property.

in Fact an Event has many Activities and Persons (people) have (or not) one Participation to many Activities with:

Event having oneToManyThrough relationship with Participation

Event having a one to Many relationship with Activity

Activity having a one to Many relationship with Participation

Participation having a one to one relationship with Person

Eventually I found a solution like this:

class EventPersonController extends Controller
{
    public function index(Event $event)
    {
        $participations = ParticipationResource::collection($event->participations);
        $result = [];
        foreach ($participations as $p) {
            array_push($result, $p->person);
        }
        $result = array_unique($result);
        return PersonResource::collection($result); {

        }
    }
}

Please or to participate in this conversation.