staudenmeir / eloquent-has-many-deep

Laravel Eloquent HasManyThrough relationships with unlimited levels
MIT License
2.67k stars 157 forks source link

Sometimes a relation returns empty collection without having issued a query or thrown an exception #119

Closed alejopages closed 3 years ago

alejopages commented 3 years ago

I've been working with the hasManyDeep method and I have been noticing that while I'm trying configure the foreign and local keys on a set of relations that are a mix of many to many, many to one, if I get a key switched around, it will not submit any queries according to the query log nor throw an exception, just returns an empty collection.

The following is the correct query and returns the expected result:

    /**
     * Get all trial sites from this region
     * 
     * @return \Staudenmeir\EloquentHasManyDeep\HasManyDeep
     */
    public function sites() {
        return $this->hasManyDeep(
            WheatTrialSite::class
            [CountyRegion::class, County::class],
            [
                'region_id', 
                'id',
                'county_id'
            ], [
                'id',
                'county_id',
                'id'
            ]
        );
    }

Switching second two local keys results in an empty collection and without a query being submitted.

    /**
     * Get all trial sites from this region
     * 
     * @return \Staudenmeir\EloquentHasManyDeep\HasManyDeep
     */
    public function sites() {
        return $this->hasManyDeep(
            WheatTrialSite::class
            [CountyRegion::class, County::class],
            [
                'region_id', 
                'id',
                'county_id'
            ], [
                'id',
                'id',
                'county_id'
            ]
        );
    }

WheatTrialSite has a foreign id to County called county_id County has only a local key called id CountyRegion has foreign keys county_id and region_id and Region has a local key called id

staudenmeir commented 3 years ago

How are you using the relationship?

alejopages commented 3 years ago

I'm querying for sites in a region. The sites are a many to one relationship with counties. Counties are a many to many with regions. The sites method exists in the Region model.

The raw sql might look something like this:

SELECT wheat_trial_sites.* FROM wheat_trial_sites
INNER JOIN county_region ON wheat_trial_sites.county_id = county_region.county_id
WHERE county_regions.region_id = ?

? would be the model's id from which the sites method is being called.
alejopages commented 3 years ago

Turns out this has to do with the way eloquent handles calling a relationship as a dynamic property. If you call the relationship with get() instead of as a dynamic property, you can view the query in the query log.