Skip to main content
Back to packages
2,862 GitHub stars

staudenmeir/eloquent-has-many-deep

View on GitHub

Description

This extended version of HasManyThrough allows relationships with unlimited intermediate models.

The package offers two ways of defining deep relationships: You can concatenate existing relationships or specify the intermediate models, foreign and local keys manually.

Concatenating Existing Relationships

Consider this example from the Laravel documentation with an additional level:
Country → has many → User → has many → Post → has many → Comment

You can define a HasManyDeep relationship by concatenating existing relationships:

class Country extends Model
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
 
public function comments(): \Staudenmeir\EloquentHasManyDeep\HasManyDeep
{
return $this->hasManyDeepFromRelations($this->posts(), (new Post())->comments());
}
 
public function posts()
{
return $this->hasManyThrough(Post::class, User::class);
}
}
 
class Post extends Model
{
public function comments()
{
return $this->hasMany(Comment::class);
}
}

Define a HasOneDeep relationship with hasOneDeepFromRelations() if you only want to retrieve a single related instance.

Constraints

By default, constraints from the concatenated relationships are not transferred to the new deep relationship. Use hasManyDeepFromRelationsWithConstraints() with the relationships as callable arrays to apply these constraints:

class Country extends Model
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
 
public function comments(): \Staudenmeir\EloquentHasManyDeep\HasManyDeep
{
return $this->hasManyDeepFromRelationsWithConstraints([$this, 'posts'], [new Post(), 'comments']);
}
 
public function posts()
{
return $this->hasManyThrough(Post::class, User::class)->where('posts.published', true);
}
}
 
class Post extends Model
{
public function comments()
{
return $this->hasMany(Comment::class)->withTrashed();
}
}

Make sure to qualify the constraints' column names if they appear in multiple tables:
->where('posts.published', true) instead of ->where('published', true)

Recent Courses on Laravel Daily

Next.js Basics for Laravel Developers

11 lessons
58 min

Queues in Laravel 13

18 lessons
1 h 12 min read

How to Build Laravel 13 API From Scratch

30 lessons
1 h 23 min

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.