Search code examples
phplaraveleloquenteloquent-relationship

Laravel - getting empty collation for 1:1 & 1:M relationships


I am having the following relational database tables. Where contacts tables has only id field and it has one person & company and many emails, phones & addresses.

Edit

Adding database diagram for better understanding. enter image description here

Here I am trying to fetch all emails, mobiles, and addresses of a specific person or company using HasManyThrough & BelongsToThrough using a packages staudenmeir/belongs-to-through & staudenmeir/eloquent-has-many-deep

My relationships are as below

class Company extends Model
{
    public function phones(): HasManyThrough
    {
        return $this->hasManyThrough(Phone::class, Contact::class, 'id', 'contact_id');
    }

    public function emails(): HasManyThrough
    {
        return $this->hasManyThrough(Email::class, Contact::class, 'id', 'contact_id');
    }

    public function addresses(): HasManyThrough
    {
        return $this->hasManyThrough(Address::class, Contact::class, 'id', 'contact_id');
    }
}


class Contact extends Model
{    
    public function addresses()
    {
        return $this->hasMany(Address::class);
    }

    public function businesses()
    {
        return $this->hasMany(Business::class);
    }

    public function person()
    {
        return $this->hasOne(Person::class);
    }
}

class Email extends Model
{
    use HasFactory, \Znck\Eloquent\Traits\BelongsToThrough;

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

    public function person(): BelongsToThrough
    {
        return $this->belongsToThrough(Person::class, Contact::class);
    }

    public function company(): BelongsToThrough
    {
        return $this->belongsToThrough(Company::class, Contact::class);
    }
}

When I try to execute the below queries it gives me an empty collection of emails, where has I am expecting a list of emails.

>>> \App\Models\Company::query()->with('emails')->where('id', 101)->first();
=> App\Models\Company {#4953
     id: 101,
     company_name: "Barnes and Small LLC",
     status: "Active",
     contact_id: 1107,
     emails: Illuminate\Database\Eloquent\Collection {#4967
       all: [],
     },
   }

>>> \App\Models\Email::where('contact_id', 1107)->get();
=> Illuminate\Database\Eloquent\Collection {#4980
     all: [
       App\Models\Email {#5008
         id: 1,
         contact_id: 1107,
         email_address: "tihin@mailinator.com",
       },
       App\Models\Contacts\Email {#5007
         id: 2,
         contact_id: 1107,
         email_address: "kecyg@mailinator.com",
       },
     ],
   }

>>>

>>> \App\Models\Contact::find(1107);
=> App\Models\Contact {#4946
     id: 1107,
     created_at: null,
     updated_at: null,
   }

>>>

Does anyone knows what I'm doing wrong here? I hope it's not too complicated with the relations.

Regards

Sunil


Solution

  • $this->hasManyThrough(
                Phone::class, 
                Contact::class,
                'company_id', // Foreign key on the Contact table...
                'contact_id' // Foreign key on the Phone table...
                'id', // Local key on the projects table...
                'id' // Local key on the environments table...
            );
    

    Your Foreign key on the Contact table for Company (3rd arg) is wrong. As per the laravel doc