staudenmeir / belongs-to-through
Laravel Eloquent BelongsToThrough relationships
Fund package maintenance!
paypal.me/JonasStaudenmeir
Installs: 5 325 408
Dependents: 18
Suggesters: 0
Security: 0
Stars: 1 136
Watchers: 21
Forks: 88
Open Issues: 0
Requires
- php: ^8.2
- illuminate/database: ^11.0
Requires (Dev)
- barryvdh/laravel-ide-helper: ^3.0
- larastan/larastan: ^2.9
- orchestra/testbench: ^9.0
- phpstan/phpstan: ^1.10
- phpstan/phpstan-mockery: ^1.1
- phpstan/phpstan-phpunit: ^1.4
- phpunit/phpunit: ^11.0
This package is auto-updated.
Last update: 2024-10-07 19:34:27 UTC
README
This inverse version of HasManyThrough
allows BelongsToThrough
relationships with unlimited intermediate models.
Supports Laravel 5.0+.
Installation
composer require staudenmeir/belongs-to-through:"^2.5"
Use this command if you are in PowerShell on Windows (e.g. in VS Code):
composer require staudenmeir/belongs-to-through:"^^^^2.5"
Versions
Usage
Consider this HasManyThrough
relationship:
Country
→ has many → User
→ has many → Post
class Country extends Model { public function posts() { return $this->hasManyThrough(Post::class, User::class); } }
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(): \Znck\Eloquent\Relations\BelongsToThrough { return $this->belongsToThrough(Country::class, User::class); } }
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(): \Znck\Eloquent\Relations\BelongsToThrough { return $this->belongsToThrough(Country::class, [User::class, Post::class]); } }
Custom Foreign Keys
You can specify custom foreign keys as the fifth argument:
class Comment extends Model { use \Znck\Eloquent\Traits\BelongsToThrough; public function country(): \Znck\Eloquent\Relations\BelongsToThrough { return $this->belongsToThrough( Country::class, [User::class, Post::class], foreignKeyLookup: [User::class => 'custom_user_id'] ); } }
Custom Local Keys
You can specify custom local keys for the relations:
VendorCustomerAddress
→ belongs to → VendorCustomer
in VendorCustomerAddress.vendor_customer_id
VendorCustomerAddress
→ belongs to → CustomerAddress
in VendorCustomerAddress.address_id
You can access VendorCustomer
from CustomerAddress
by the following
class CustomerAddress extends Model { use \Znck\Eloquent\Traits\BelongsToThrough; public function vendorCustomer(): \Znck\Eloquent\Relations\BelongsToThrough { return $this->belongsToThrough( VendorCustomer::class, VendorCustomerAddress::class, foreignKeyLookup: [VendorCustomerAddress::class => 'id'], localKeyLookup: [VendorCustomerAddress::class => 'address_id'], ); } }
Table Aliases
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(): \Znck\Eloquent\Relations\BelongsToThrough { return $this->belongsToThrough( Comment::class, Comment::class . ' as alias', foreignKeyLookup: [Comment::class => 'parent_id'] ); } }
Use the HasTableAlias
trait in the models you are aliasing:
class Comment extends Model { use \Znck\Eloquent\Traits\HasTableAlias; }
Soft Deleting
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(): \Znck\Eloquent\Relations\BelongsToThrough { return $this->belongsToThrough(Country::class, [User::class, Post::class]) ->withTrashed('users.deleted_at'); } } class User extends Model { use SoftDeletes; }
Contributing
Please see CONTRIBUTING and CODE OF CONDUCT for details.