friendsofhyperf/compoships

Hyperf 关系支持复合/多键。

v3.1.31 2024-06-17 01:41 UTC

README

Latest Stable Version Total Downloads License

Compoships 允许在 Hyperf 的 Model ORM 中基于两个(或更多)列指定关系。在处理第三方或现有模式/数据库时,经常需要在 Eloquent 关系定义中匹配多个列的需求。

问题

Eloquent 不支持复合键。因此,无法通过匹配多个列来从一个模型定义一个与另一个模型的关系。当尝试使用 where 子句(如下例所示)来预加载关系时,这将不会工作,因为在处理关系时 $this->team_id 为空。

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);
    }
}

安装

安装 Compoships 的推荐方式是通过 Composer

composer require friendsofhyperf/compoships

用法

使用 FriendsOfHyperf\Compoships\Database\Eloquent\Model

只需让您的模型类继承 FriendsOfHyperf\Compoships\Database\Eloquent\Model 基类。该 FriendsOfHyperf\Compoships\Database\Eloquent\Model 扩展了 Eloquent 基类,而不改变其核心功能。

使用 FriendsOfHyperf\Compoships\Compoships 特性

如果由于某些原因您不能从 FriendsOfHyperf\Compoships\Database\Eloquent\Model 继承模型,您可以利用 FriendsOfHyperf\Compoships\Compoships 特性。只需在您的模型中使用此特性。

注意:为了从模型 A 定义一个多列关系到另一个模型 B,两个模型必须要么扩展 FriendsOfHyperf\Compoships\Database\Eloquent\Model,要么使用 FriendsOfHyperf\Compoships\Compoships 特性。

语法

...现在我们可以通过匹配两个或更多列(通过传递列数组而不是字符串)来定义从模型 A 到模型 B 的关系。

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']);
    }
}

我们可以使用相同的语法来定义关系的反方向

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']);
    }
}

示例

例如,假设我们有一个任务列表与类别,由多个用户团队管理,其中

  • 一个任务属于一个类别
  • 一个任务被分配给一个团队
  • 一个团队有许多用户
  • 一个用户属于一个团队
  • 一个用户负责一个任务类别的任务

负责特定任务的用户是负责该团队内部类别的当前用户。

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']);
    }
}

再次,使用相同的语法定义关系的反方向

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']);
    }
}

联系方式

许可证

MIT