friendsofhyperf / compoships
Hyperf relationships with support for composite/multiple keys.
Fund package maintenance!
huangdijia
hdj.me/sponsors
Requires
- hyperf/database: ~3.1.0
- hyperf/stringable: ~3.1.0
- hyperf/support: ~3.1.0
- hyperf/tappable: ~3.1.0
Suggests
- awobaz/blade-active: Blade directives for the Laravel 'Active' package
- awobaz/eloquent-auto-append: Automatically append accessors to model serialization
- awobaz/eloquent-mutators: Reusable mutators (getters/setters) for Laravel 5's Eloquent
- awobaz/syntactic: Syntactic sugar for named and indexed parameters call.
- dev-main / 3.1.x-dev
- v3.1.48
- v3.1.41
- v3.1.31
- v3.1.28.1
- v3.1.27
- v3.1.17
- v3.1.7
- v3.1.6
- v3.1.1
- v3.1.0
- v3.1.0-rc.14
- v3.1.0-rc.4
- v3.1.0-beta.20
- v3.1.0-beta.15
- v3.1.0-beta.9
- v3.1.0-beta.1
- 3.0.x-dev
- v3.0.114
- v3.0.113
- v3.0.93
- v3.0.85
- v3.0.80
- v3.0.70
- v3.0.55
- v3.0.52
- v3.0.51
- v3.0.49
- v3.0.44
- v3.0.42
- v3.0.40
- v3.0.35
- v3.0.14
- v3.0.2
- v3.0.0
- v3.0.0-rc.20
- v3.0.0-rc.16
- v3.0.0-rc.12
- v3.0.0-rc.11
- 2.0.x-dev
- v2.0.28
- v2.0.24
- v2.0.22
- v2.0.20
- v2.0.19
- v1.0.0-beta.2
- v1.0.0-beta1
- v0.1.0
This package is auto-updated.
Last update: 2024-12-04 02:41:27 UTC
README
Compoships offers the ability to specify relationships based on two (or more) columns in Hyperf's Model ORM. The need to match multiple columns in the definition of an Eloquent relationship often arises when working with third party or pre existing schema/database.
The problem
Eloquent doesn't support composite keys. As a consequence, there is no way to define a relationship from one model to another by matching more than one column. Trying to use where clauses
(like in the example below) won't work when eager loading the relationship because at the time the relationship is processed $this->team_id is null.
namespace App; use Hyperf\Database\Model\Model; class User extends Model { public function tasks() { //WON'T WORK WITH EAGER LOADING!!! return $this->hasMany(Task::class)->where('team_id', $this->team_id); } }
Installation
The recommended way to install Compoships is through Composer
composer require friendsofhyperf/compoships
Usage
Using the FriendsOfHyperf\Compoships\Database\Eloquent\Model
class
Simply make your model class derive from the FriendsOfHyperf\Compoships\Database\Eloquent\Model
base class. The FriendsOfHyperf\Compoships\Database\Eloquent\Model
extends the Eloquent
base class without changing its core functionality.
Using the FriendsOfHyperf\Compoships\Compoships
trait
If for some reasons you can't derive your models from FriendsOfHyperf\Compoships\Database\Eloquent\Model
, you may take advantage of the FriendsOfHyperf\Compoships\Compoships
trait. Simply use the trait in your models.
Note: To define a multi-columns relationship from a model A to another model B, both models must either extend FriendsOfHyperf\Compoships\Database\Eloquent\Model
or use the FriendsOfHyperf\Compoships\Compoships
trait
Syntax
... and now we can define a relationship from a model A to another model B by matching two or more columns (by passing an array of columns instead of a string).
namespace App; use Hyperf\Database\Model\Model; class A extends Model { use \FriendsOfHyperf\Compoships\Compoships; public function b() { return $this->hasMany('B', ['foreignKey1', 'foreignKey2'], ['localKey1', 'localKey2']); } }
We can use the same syntax to define the inverse of the relationship:
namespace App; use Hyperf\Database\Model\Model; class B extends Model { use \FriendsOfHyperf\Compoships\Compoships; public function a() { return $this->belongsTo('A', ['foreignKey1', 'foreignKey2'], ['ownerKey1', 'ownerKey2']); } }
Example
As an example, let's pretend we have a task list with categories, managed by several teams of users where:
- a task belongs to a category
- a task is assigned to a team
- a team has many users
- a user belongs to one team
- a user is responsible for one category of tasks
The user responsible for a particular task is the user currently in charge for the category inside the team.
namespace App; use Hyperf\Database\Model\Model; class User extends Model { use \FriendsOfHyperf\Compoships\Compoships; public function tasks() { return $this->hasMany(Task::class, ['team_id', 'category_id'], ['team_id', 'category_id']); } }
Again, same syntax to define the inverse of the relationship:
namespace App; use Hyperf\Database\Model\Model; class Task extends Model { use \FriendsOfHyperf\Compoships\Compoships; public function user() { return $this->belongsTo(User::class, ['team_id', 'category_id'], ['team_id', 'category_id']); } }