Eloquent与条件有很多关系
Posted
技术标签:
【中文标题】Eloquent与条件有很多关系【英文标题】:Eloquent hasMany relationship with condition 【发布时间】:2018-08-20 17:32:17 【问题描述】:我有一个具有属性“id”、“orderer_user_id”和“contractor_user_id”的模型合同。 我有一个具有“contract_id”、“user_id”和“已签名”属性的模型签名。 我在合同上有一个 hasMany 关系来检索属于合同的签名。 每个合同都有两个签名,一个属于订购者,另一个属于承包商。
我需要获取尚未签署其订购者签名的所有合同(因此,'contract_id' 必须是其父级的 id,'user_id' 必须是其父级的 'orderer_user_id',而 'signed' 必须是假的)
Laravel/Eloquent 的实现方式是什么? 我知道我可以编写一个 foreach 循环并迭代所有合同,检查其签名,然后使用未签名的订购者签名构建一组合同,但感觉很笨拙。 我一直在玩弄关系/有/没有等,但我似乎无法得到正确的结果。
【问题讨论】:
添加一个您到目前为止所做的工作示例会很有帮助 【参考方案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 模型中引入承包商和订购者的具体关系:
// 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 以获取更多信息。
【讨论】:
感谢您的反应。我有你提到的确切关系。关键是所有合同在数据库中都有两个签名子节点,但我需要找出哪些合同有一个签名,其中字段“已签名”= false。我现在这样做的方式可行,但感觉有点笨拙: $cons = Contract::get(); foreach ($cons as $con) if ($con->ordererSigned() == true && $con->contractorSigned() == false) $result[] = $con; 您还可以通过whereHas
方法为您添加附加条件,我已经更新了我的答案。这能满足您的需求吗?【参考方案2】:
您可以创建一个应对或定义您的多重关系,无论何时调用它(添加 ->where()->select()...)。
就我个人而言,我会创建一个作用域,这样您就可以随时调用关系,并在需要时应用作用域,从而使两个函数(最终就是函数)独立。
https://laravel.com/docs/5.6/eloquent#local-scopes
【讨论】:
以上是关于Eloquent与条件有很多关系的主要内容,如果未能解决你的问题,请参考以下文章
与where子句查询的Eloquent嵌套关系在false条件下返回集合
关系方法必须在 laravel eloquent 中返回一个对象
Laravel Eloquent 根据数据透视表字段条件获取多对多关系