ahmedde's avatar

Excluding current model from nested HasMany Relationship?

This relationship retrieves all videos from the same category:

Model Video {

...

    public function relatedByCategory(): HasMany
    {
        return $this->hasMany(Video::class, 'category_id', 'category_id')
            ->where('id', '!=', $this->id); // Exclude the current video
    }

The problem is that it still retrieves the current video itself even with where('id', '!=', $this->id);. How to achieve this goal?

0 likes
5 replies
Snapey's avatar

If this does not work, I would probably create a scope

    public function relatedByCategory(): HasMany
    {
        return $this->hasMany(Video::class, 'category_id', 'category_id');            
    }

    public function scopeNotSelf($query)
    {
        $query->where('id', '!=', $this->id); // Exclude the current video
    }

and use it like $relatedVideos = $video->relatedByCategory()->notSelf()->get();

1 like
ahmedde's avatar

@Snapey This is, interestingly, still retrieving the current video. I did some debugging and for some reason $this->id is evaluated to null.

This is the results of the query

ahmedde's avatar

@Snapey Debugging more into the issue:

This query, with eager loading, Retruns the same video in the results

Video::with('relatedByCategory')->find('VIDEO_ID')->relatedByCategory

Without Eager loading, it excludes the current video and works as expected.

Video::find('VIDEO_ID')->relatedByCategory

Does eager loading affect the relationship query?

kevinbui's avatar

Defining a relationship this way is very unconventional and surely does not scale. I suggest defining a different relationship or just writing a database query scope.

Also, ->where('id', '!=', $this->id) can be rewritten to simply ->whereKeyNot($this->id).

Please or to participate in this conversation.