Eloqent与条件有很多关系

时间:2018-03-12 16:01:05

标签: php laravel eloquent has-many relationships

我有一个带有属性'id','orderer_user_id'和'contractor_user_id'的模型合约。 我有一个模型签名,其属性为'contract_id','user_id'和'signed'。 我在Contract上有一个hasMany关系来检索属于合同的签名。 每份合同都有两个签名,一个属于订货人,另一个属于承包商。

我需要获得所有尚未签署其订货人签名的合同(因此'contract_id'必须是其父级的ID,'user_id'必须是其父级的'orderer_user_id'且'签名'必须是假的)

实现这一目标的Laravel / Eloquent方法是什么? 我知道我可以只编写一个foreach循环并迭代所有合同,检查其签名,然后使用未签名的订购者签名构建合同集合,但感觉很笨拙。 我一直在玩关系/有/没有等等,但我似乎无法得到正确的结果。

2 个答案:

答案 0 :(得分:1)

您应该在合同模型上实施关系

// 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了解更多信息。

答案 1 :(得分:0)

您可以创建一个应对或在您的多重关系中定义您希望在调用它时所希望的内容(添加 - &gt; where() - &gt; select()...)。

就个人而言,我制作了一个范围,这样你就可以随时调用关系,只需在需要时应用范围,使两个函数(它们最终都是函数)成为独立的。

  

https://laravel.com/docs/5.6/eloquent#local-scopes