情况如下:我有4个型号。
这些对象如下相关:
我正在尝试在Invoice上编写timeline()关系,以考虑这些对象的优先级顺序。如果债务人有时间表,则使用它。否则,如果发票有时间轴,则使用它。最后,如果以上都没有找到,则使用债权人的时间表。
我已经看了很多,我正在努力寻找解决方案。在我看来,这很简单,但事实证明并非如此。
方法我已经无济于事了......
将原始select语句放入select中将返回所需时间轴的_rowid的关系中:
return $this->hasOne('Timeline', '_rowid', 'SELECT ...')
同样的想法,使用DB :: raw():
return $this->hasOne('Timeline', '_rowid', DB::raw('SELECT ...'))
尝试使用选择和连接加载到关系查询:
return $this->hasOne('Timeline', '_rowid', 'timeline_rowid')
->select('Timelines_Country.*')
->join(DB::raw('(select if(Debitor.timeline_rowid is not null, Debitor.timeline_rowid, if(Invoice.timeline_rowid is not null, Invoice.timeline_rowid, Creditor.timeline_rowid)) as timeline_rowid from Invoice join Debitor on Invoice.unique_string_cd = Debitor.unique_string_cd join Creditor on Creditor.id = Invoice.creditor_id where Debitor.timeline_rowid is not null and Invoice.timeline_rowid is not null) temp'), function($join){
$join->on('Timelines_Country._rowid', '=', 'temp.timeline_rowid');
})
->whereNotNull('temp.timeline_rowid');
最终的解决方案似乎最接近,但它仍然包括“WHERE IN(?,?,?)”的标准关系查询,其中列表是发票集合中的timeline_rowids,这导致某些时间线仍然不是找到。
提前感谢您的帮助!
答案 0 :(得分:1)
确定。我想我从根本上误解了人际关系的运作方式。因为它们是在已经实例化模型之后加载的,所以关系查询的其中部分的数组是通过访问模型的属性构建的。一旦我发现它,它实际上是一个简单的解决方案。
我编写了这个函数,它根据关系返回timeline_rowid:
public function getDerivedTimelineAttribute()
{
if ($this->debtor && $this->debtor->timeline_rowid)
{
return $this->debtor->timeline_rowid;
}
else if ($this->timeline_rowid)
{
return $this->timeline_rowid;
}
else if ($this->creditor->timeline_rowid)
{
return $this->creditor->timeline_rowid;
}
else
{
Log::Debug("can't find timeline", ['cdi' => $this->unique_string_cdi]);
return 0;
}
}
然后将关系修改为:
public function timeline()
{
return $this->hasOne('Timeline', '_rowid', 'derivedTimeline');
}
我希望这有助于其他人。把我搞砸了一段时间搞清楚了!