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

boyjarv's avatar

relationship resource file and how to include that to show an array of contact for company?

Hi I currently have a relationship between two tables, Contacts Companies

Great I am getting an object of company for each contact but when I try and get an an array of contacts for each company I'm just getting NULL back?! company resource:

<?php

namespace App\Http\Resources;

use App\Http\Resources\ContactResource;
use Illuminate\Http\Resources\Json\JsonResource;

class CompanyResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    public function toArray($request)
    {
        return [
            "id" => $this->id,
            "name" => $this->name,
            "email" => $this->email,
            "phone" => $this->phone,
            "address" => $this->address,
            "town_city" => $this->town_city,
            "region_county" => $this->region_county,
            "country_code" => $this->country_code,
            "post_code" => $this->post_code,
            "contacts" => new ContactResource($this->contact)
        ];
    }
}

Company model:

public function contacts() {
        return $this->hasMany(Contact::class, 'contact_id', 'id');
    }
0 likes
31 replies
tykus's avatar
ContactResource::collection($this->contacts)
boyjarv's avatar

@tykus I used this in the CompanyResource and it doesn't like it:

<?php

namespace App\Http\Resources;

use App\Http\Resources\ContactResource;
use Illuminate\Http\Resources\Json\JsonResource;

class CompanyResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    public function toArray($request)
    {
        return [
            "id" => $this->id,
            "name" => $this->name,
            "email" => $this->email,
            "phone" => $this->phone,
            "address" => $this->address,
            "town_city" => $this->town_city,
            "region_county" => $this->region_county,
            "country_code" => $this->country_code,
            "post_code" => $this->post_code,
            "contacts" => new ContactResource::collection($this->contact)
        ];
    }
}

it's saying: syntax error, unexpected identifier "collection", expecting variable or "$" Unexpected 'Name'.intelephense(1001)

tykus's avatar

@boyjarv no new

"contacts" => ContactResource::collection($this->contacts)
1 like
cwhite's avatar

@boyjarv

::collection is a static method (i.e., you don't instantiate an object to use it). The last line should be

            "contacts" => ContactResource::collection($this->contact)
mubeensaeed's avatar

@boyjarv Include contacts when you call company model like this:

'contacts' => ContactResource::collection($this->contacts),

Try $this->contacts instead of $this->contact. Because there is HasMany relation for contacts

boyjarv's avatar

now I'm getting:

Column not found: 1054 Unknown column &#039;contacts.contact_id&#039; in &#039;where clause&#039; (SQL: select * from `contacts` where `contacts`.`contact_id` = 1 and `contacts`.`contact_id` is not null) in file /Users/johnbiddulph/Documents/jbsites/laravel/laravel-jwt/vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 759
boyjarv's avatar

company model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use App\Models\Contact;

class Company extends Model
{
    use HasFactory;
    protected $fillable = [
        'first_name',
        'last_name',
        'email',
        'phone',
        'address',
        'town_city',
        'region_county',
        'country_code',
        'post_code',
        'notes'
    ];

    public function contacts() {
        return $this->hasMany(Contact::class, 'contact_id', 'id');
    }
}

contact model:

<?php

namespace App\Models;

use App\Models\Company;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Contact extends Model
{
    use HasFactory;
    protected $fillable = [
        'company_id',
        'first_name',
        'last_name',
        'email',
        'phone',
        'address',
        'town_city',
        'region_county',
        'country_code',
        'post_code'
    ];

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

I think it's this line that is wrong as there is no contact_id - not sure what to change it to?!

I changed it to

public function contacts() {
        return $this->hasMany(Contact::class, 'id', 'contact_id');
    }

I am now getting an empty array for each company?!

{
            "id": 4,
            "name": "Hayes-Spinka",
            "email": "charlotte.gorczany.com"
            "contacts": []
        },
tykus's avatar

@boyjarv the Contact has a company_id which should be used in the relationship by default; you don't need to specify the FK unless it is non-conventional:

// Company model
public function contacts()
{
    return $this->hasMany(Contact::class);
}
// Contact model
public function company()
{
    return $this->belongsTo(Company::class);
}
mubeensaeed's avatar

@boyjarv Try to update you relation to this:

public function contacts() { return $this->hasMany(Contact::class, 'company_id', 'id'); }

boyjarv's avatar

postman is saying:

Error: socket hang up I've tried:

public function contacts()
{
    return $this->hasMany(Contact::class);
}

and

public function contacts()
{
    return $this->hasMany(Contact::class, 'company_id', 'id');
}
boyjarv's avatar

I'm. now getting:

Error: Call to a member function first() on null in file /Users/johnbiddulph/Documents/jbsites/laravel/laravel-jwt/vendor/laravel/framework/src/Illuminate/Http/Resources/CollectsResources.php on line 34
tykus's avatar

@boyjarv can you show the full toArray methods for the Resource class(es) - it seems you are passing null where a Collection is expected

boyjarv's avatar

CompanyResource:

	<?php

namespace App\Http\Resources;

use App\Http\Resources\ContactResource;
use Illuminate\Http\Resources\Json\JsonResource;

class CompanyResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    public function toArray($request)
    {
        return [
            "id" => $this->id,
            "name" => $this->name,
            "email" => $this->email,
            "phone" => $this->phone,
            "address" => $this->address,
            "town_city" => $this->town_city,
            "region_county" => $this->region_county,
            "country_code" => $this->country_code,
            "post_code" => $this->post_code,
            "contacts" =>  ContactResource::collection($this->contact)
        ];
    }
}

ContactResource:

<?php

namespace App\Http\Resources;

use App\Http\Resources\CompanyResource;
use Illuminate\Http\Resources\Json\JsonResource;

class ContactResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    public function toArray($request)
    {
        return [
            "id" => $this->id,
            "first_name" => $this->first_name,
            "last_name" => $this->last_name,
            "email" => $this->email,
            "phone" => $this->phone,
            "address" => $this->address,
            "town_city" => $this->town_city,
            "region_county" => $this->region_county,
            "country_code" => $this->country_code,
            "post_code" => $this->post_code,
            "created_at" => $this->created_at,
            "company" => new CompanyResource($this->company)
        ];
    }
}

tykus's avatar

@boyjarv the relationship is contacts, not contact, right?

"contacts" =>  ContactResource::collection($this->contacts)
boyjarv's avatar

@tykus yes thats right ,

I've tried this:

"contacts" =>  ContactResource::collection($this->contacts)

but it doesn't work, Laravel breaks and changes the localhost to: http://127.0.0.1:8001 I have to run php artisan serve again

here is the relationship in the Company model

public function contacts() {
        return $this->hasMany(Contact::class);
    }
boyjarv's avatar

ok so I found storage/logs log file I cleared it out re-ran php artisan serve and then logged in and clicked on Companies, nothing was written to the log file

tykus's avatar

@boyjarv and is this just happening since you added that ContactResource::collection($this->contacts) line???

Something is not adding up here.

boyjarv's avatar

@tykus Thank you for this @tykus

In my Contact Resource I have:

return [
            "id" => $this->id,
            "first_name" => $this->first_name,
            "last_name" => $this->last_name,
            "email" => $this->email,
            "phone" => $this->phone,
            "address" => $this->address,
            "town_city" => $this->town_city,
            "region_county" => $this->region_county,
            "country_code" => $this->country_code,
            "post_code" => $this->post_code,
            "created_at" => $this->created_at,
            "company" => new CompanyResource($this->whenLoaded('company'))
        ];

and the CompanyResource I have:

return [
            "id" => $this->id,
            "name" => $this->name,
            "email" => $this->email,
            "phone" => $this->phone,
            "address" => $this->address,
            "town_city" => $this->town_city,
            "region_county" => $this->region_county,
            "country_code" => $this->country_code,
            "post_code" => $this->post_code,
            "contacts" => ContactResource::collection($this->contacts)
        ];

the Contacts now are showing for each company but the company is now not showing for the contacts?!

1 like
tykus's avatar

@boyjarv what do you suppose whenLoaded means? You would need to load the company relationship on the contacts if you want to display it, e.g. in the Controller before you make the top level Company resource

$company->load('contacts.company');

Make sure you conditionally load the contacts in the CompanyResource, or you go into another infinite loop

ContactResource::collection($this->whenLoaded($this->contacts))

BUT what is the purpose of your Resources showing contacts inside company, and company inside each contact, and contacts inside company, and company inside each contact, and contacts inside company, and company inside each contact, and ... so on? It's got to end somewhere!

boyjarv's avatar

@tykus Thank you so much for your help! I modified my Contact Controller to:

public function index()
    {
        $contacts = Contact::paginate(15);

        return ContactResource::collection($contacts->load('company'));
    }

Please or to participate in this conversation.