This inverse version of HasManyThrough
allows BelongsToThrough
relationships with unlimited intermediate models.
Supports Laravel 5.0+.
composer require staudenmeir/belongs-to-through:"^2.5"
Consider this HasManyThrough
relationship:
Country
→ has many → User
→ has many → Post
class Country extends Model
{
public function posts()
{
return $this->hasManyThrough('App\Post', 'App\User');
}
}
Use the BelongsToThrough
trait in your model to define the inverse relationship:
Post
→ belongs to → User
→ belongs to → Country
class Post extends Model
{
use \Znck\Eloquent\Traits\BelongsToThrough;
public function country()
{
return $this->belongsToThrough('App\Country', 'App\User');
}
}
You can also define deeper relationships:
Comment
→ belongs to → Post
→ belongs to → User
→ belongs to → Country
Supply an array of intermediate models as the second argument, from the related (Country
) to the parent model (Comment
):
class Comment extends Model
{
use \Znck\Eloquent\Traits\BelongsToThrough;
public function country()
{
return $this->belongsToThrough('App\Country', ['App\User', 'App\Post']);
}
}
You can specify custom foreign keys as the fifth argument:
class Comment extends Model
{
use \Znck\Eloquent\Traits\BelongsToThrough;
public function country()
{
return $this->belongsToThrough(
'App\Country',
['App\User', 'App\Post'],
null,
'',
['App\User' => 'custom_user_id']
);
}
}
If your relationship path contains the same model multiple times, you can specify a table alias (Laravel 6+):
class Comment extends Model
{
use \Znck\Eloquent\Traits\BelongsToThrough;
public function grandparent()
{
return $this->belongsToThrough(
'App\Comment',
'App\Comment as alias',
null,
'',
['App\Comment' => 'parent_id']
);
}
}
Use the HasTableAlias
trait in the models you are aliasing:
class Comment extends Model
{
use \Znck\Eloquent\Traits\HasTableAlias;
}
By default, soft-deleted intermediate models will be excluded from the result. Use withTrashed()
to include them:
class Comment extends Model
{
use \Znck\Eloquent\Traits\BelongsToThrough;
public function country()
{
return $this->belongsToThrough('App\Country', ['App\User', 'App\Post'])
->withTrashed('users.deleted_at');
}
}
class User extends Model
{
use SoftDeletes;
}
Please see CONTRIBUTING and CODE OF CONDUCT for details.