Michael Ploeckinger
Michael Ploeckinger

Reputation: 1634

Laravel 5.4 hasManyThrough returns wrong query

i have in my Seller Model following relation

public function members()
{
    return $this->hasManyThrough(Member::class, Organization::class, 'seller_id', 'organization_id', 'id');
}

Table Structure:

sellers

seller_organizations

organizations

organization_members

A Seller has many organizations and an organization has many members.

In my Seller\MemberController i want to parse the query like

 private function parseRequest(Request $request, Seller $seller)
    {
        $query = $seller->organizationMembers();
}

Response:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'organizations.seller_id' in 'where clause' (SQL: select count(*) as aggregate from organization_members inner join organizations on organizations.id = organization_members.organization_id where organizations.seller_id = 123)

How can i tell laravel that it needs to look in seller_organizations table for the correct relation?

thanks in advance!

Upvotes: 0

Views: 182

Answers (3)

Namoshek
Namoshek

Reputation: 6544

You can build a function with a simple query like this one:

class Seller
{
    public function organizationMembers()
    {
        return OrganizationMember::query()
            ->whereHas('organization', function ($query) {
                $query->whereHas('sellers', function ($query) {
                    $query->where('id', $this->id);
                });
            });
    }
}

But you will not be able to use a built-in relationship type. So eager loading will not be available for you in this scenario.

Upvotes: 1

Elisha Senoo
Elisha Senoo

Reputation: 3594

Your peculiar case is different from the generic solution Laravel provides out of the box. Create a belongsToMany relationship on the Seller model for organizations like this:

public function organizations()
    {
        return $this->belongsToMany(Organization::class, 'seller_organizations', 'seller_id', 'organization_id');
    }

On the organization model, add a hasMany members relationship like this:

public function organizationMembers()
    {
        return $this->hasMany(OrganizationMember::class);
    }

Then finally in the Seller model, add the members relationship as follows:

public function members()
    {
        $members= new Illuminate\Database\Eloquent\Collection;

        foreach($this->organizations as $organization)
        {
            $members = $members->merge($organization->organizationMembers->get());
        }

        return $members->unique();
    }

Upvotes: 1

Kenny Horna
Kenny Horna

Reputation: 14241

It seems that Sellers and Organizations make a many-to-many relationship, so in that case you couldn't apply the Has Many Through because it is the union of two one-to-many relationship on the same direction, like this:

|A| has many |B|
|B| has many |c|

So, when doing the query it follows this logic:

|A| has many |C| through |B|.

You could define your own relationship tho, check this answer. Just remember to change ->lists() with ->pluck(...).

Upvotes: 0

Related Questions