Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

me@bayes-shelton.co.uk's avatar

Issue with Eloquent: API Resources - Conditional Relationships

I think I might have found a bug in Laravel, please see the below code:

I am hitting an endpoint which is /api/users/1

public function show(User $user)
{
    return new UserResource($user);
}

My Resource looks like the below:

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    public function toArray($request)
    {

        //dd($this);

        return [
            'uuid'               => $this->uuid,
            'name'               => $this->name,
            'currency'           => $this->currency,
            'company'            => new CompanyResource($this->whenLoaded('company')),
            'created_at'         => $this->created_at,
            'updated_at'         => $this->updated_at,
        ];
    }
}

Now I would expect the company property not to return in the JSON however it does, can anyone see a reason why the company relation is being loaded and added to the JSON response when I am not using ->with() anywhere in my code?

Sorry if this is a total n00b mistake but I want to properly understand the new API resource stuff in Laravel and I feel like I am making a mistake.

0 likes
11 replies
devfrey's avatar

As far as I can tell, it's perfectly valid.

However, I'm guessing you're still loading the relation somewhere else in your code. Perhaps a $with on the model class, or you're accessing the relationship (attribute) directly.

me@bayes-shelton.co.uk's avatar

Yeah, I cannot see anything in the model etc. The docs on this as a little poor IMHO.

I also noticed that the docs don't show route model binding which I would have thought would be what everyone is doing.

devfrey's avatar

@ME@BAYES-SHELTON.CO.UK - Route model binding is in the docs, actually.

But could you perhaps share some more code related to your problem? Could you include your UserResource?

me@bayes-shelton.co.uk's avatar

@DEVFREY - I knew route model binding was still in, I meant they don't show the resource collections using route model binding which seems to be the most logical setup

me@bayes-shelton.co.uk's avatar

So my User model is:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class User extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [

    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'lender_id', 'tranche_id', 'transaction_tranche_id'
    ];

    /**
     * @var array
     */
    protected $guarded = [
        'id', 'uuid'
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [

    ];

    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = [
        //'percent_of_tranche'
    ];

    /**
     * @return string
     */
    public function getRouteKeyName()
    {
        return 'uuid';
    }

    /**
     * Set the user's UUID.
     *
     * @param  string  $value
     * @return void
     */
    public function setUuidAttribute()
    {
        $this->attributes['uuid'] = strtolower(Str::random(10));
    }

    public function company()
    {
        return $this->belongsTo(Company::class);
    }
}
devfrey's avatar

@ME@BAYES-SHELTON.CO.UK - And your UserResource class?

staudenmeir's avatar

What's the result of dd($this->getRelations()); in UserResource::toArray()?

me@bayes-shelton.co.uk's avatar

Hey @staudenmeir

array:1 [
  "company" => Company {#356
    #fillable: []
    #hidden: array:2 [
      0 => "id"
      1 => "company_id"
    ]
    #guarded: array:2 [
      0 => "id"
      1 => "uuid"
    ]
    #casts: []
    #appends: []
    #connection: "mysql"
    #table: "companies"
    #primaryKey: "id"
    #keyType: "int"
    +incrementing: true
    #with: []
    #withCount: []
    #perPage: 15
    +exists: true
    +wasRecentlyCreated: false
    #attributes: array:8 [
      "id" => 1
      "uuid" => "r7kn4glkqm"
      "name" => "Company Q56"
      "amount" => 57294490005
      "currency" => "EUR"
      "transaction_id" => 1
      "created_at" => "2019-05-16 23:30:14"
      "updated_at" => "2019-05-16 23:30:14"
    ]
    #original: array:8 [
      "id" => 1
      "uuid" => "r7kn4glkqm"
      "name" => "Company Q56"
      "amount" => 57294490005
      "currency" => "EUR"
      "transaction_id" => 1
      "created_at" => "2019-05-16 23:30:14"
      "updated_at" => "2019-05-16 23:30:14"
    ]
    #touches: []
    +timestamps: true
    #visible: []
  }
]```
me@bayes-shelton.co.uk's avatar
Level 2

So I have managed to fix it!!

The relation was loading because I had an attribute on the model that used property from the relation in the model.

Please or to participate in this conversation.