我有一个模型合约,属性为'id'、'orderer_user_id'和'contractor_user_id'。我有一个带有属性"contract_id"、"user_id"和"签名"的模型签名。我在合同上有很多关系来检索属于合同的签名。每个合同都有两个签名,一个属于订货人,另一个属于承包商。
我需要获取所有尚未签署其订货人签名的合同(因此"contract_id"必须是其父级的ID,"user_id"必须是其父级的"orderer_user_id",并且"已签名"必须是假的(
拉拉维尔/雄辩的方法是什么?我知道我可以编写一个 foreach 循环并迭代所有合约,检查其签名,然后构建具有未签名的排序者签名的合约集合,但这感觉很笨拙。我一直在玩关系/有/没有等,但我似乎无法得到正确的结果。
您应该在合约模型上实现关系
// Contract.php
public function signatures() {
// add proper parameters 2nd: foreign key and 3rd: local key if
// your Database design is not respecting laravel/eloquent naming guidelines
return $this->hasMany(Signature::class);
}
为了检索未签署的合同,这应该有效:
$unsignedContracts = Contract::whereHas("signatures", '<', 2)->get();
我认为这也应该完全不涵盖任何条目,但如果没有,您也可以尝试一下
$unsignedContracts = Contract::whereDoesntHave("signatures")
->orWhereHas("signatures", '<', 2)->get();
如果要使用附加条件查询所有签名,也可以这样做:
$unsignedContracts = Contract::whereHas("signatures", function($q) {
$q->where("signed","=",false);
})->get()
您还可以在签名模型中为承包商和订货人引入具体关系:
// Signature.php
public function contractor() {
return $this->belongsTo(User::class, "contractor_user_id", "id");
}
public function orderer() {
return $this->belongsTo(User::class, "orderer_user_id", "id");
}
有了这些,您应该能够做到这一点:
// this should return all contracts where one of the
// required users has not signed yet
$unsignedContracts = Contract::where(function($q) {
$q->whereDoesntHave("contractor")
->orWhereDoesntHave("orderer");
})->get();
Laravel文档是相当不错的恕我直言,看看
https://laravel.com/docs/5.6/eloquent-relationships#querying-relations 以获取更多输入。
你可以在你的多重关系上定义你想要成为什么,只要你调用它(添加一个 ->where((->select((...(。
就个人而言,我会创建一个作用域,以便您可以随时调用关系,并在需要时应用作用域,使两个函数(最终就是函数(独立。
https://laravel.com/docs/5.6/eloquent#local-scopes