Compoships
Compoships 提供了在 Hyperf 的 Model ORM 中基於兩個(或更多)列指定關係的能力。當處理第三方或預先存在的模式/資料庫時,通常會出現需要在 Eloquent 關係的定義中匹配多個列的情況。
問題
Eloquent 不支援複合鍵。因此,無法透過匹配多個列來定義從一個模型到另一個模型的關係。嘗試使用 where
子句(如下例所示)在預載入關係時不起作用,因為在處理關係時 $this->team_id 為 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);
}
}
安裝
推薦透過 Composer 安裝 Compoships 元件。
composer require friendsofhyperf/compoships
使用
使用 FriendsOfHyperf\Compoships\Database\Eloquent\Model
類
只需讓您的模型類派生自 FriendsOfHyperf\Compoships\Database\Eloquent\Model
基類。FriendsOfHyperf\Compoships\Database\Eloquent\Model
擴充套件了 Eloquent
基類,而不改變其核心功能。
使用 FriendsOfHyperf\Compoships\Compoships
trait
如果由於某些原因您無法從 FriendsOfHyperf\Compoships\Database\Eloquent\Model
派生您的模型,您可以利用 FriendsOfHyperf\Compoships\Compoships
trait。只需在您的模型中使用該 trait。
注意: 要從模型 A 到另一個模型 B 定義多列關係,兩個模型都必須擴充套件 FriendsOfHyperf\Compoships\Database\Eloquent\Model
或使用 FriendsOfHyperf\Compoships\Compoships
trait
用法
... 現在我們可以透過匹配兩個或更多列(透過傳遞列陣列而不是字串)來定義從模型 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']);
}
}