【问题标题】:Laravel Conditional RelationshipLaravel 条件关系
【发布时间】:2015-06-24 14:33:36
【问题描述】:

情况如下:我有 4 个模型。

  • 发票
  • 债权人
  • 债务人
  • 时间表

这些对象是这样相关的:

  • 发票有债权人、债务人,并且可能有时间线。
  • 债务人也可能有时间线。
  • 债权人有时间表。

我正在尝试在 Invoice 上编写时间线()关系以考虑这些对象的优先级顺序。如果债务人有时间线,则使用它。否则,如果发票有时间线,则使用它。最后,如果以上都没有找到,则使用债权人的时间线。

我已经环顾四周,正在努力寻找解决方案。在我看来,这很简单,尽管事实证明并非如此。

我采取的方法无济于事......

将原始选择语句放入关系中,其中选择将返回所需时间线的 _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 (?,?,?)”的标准关系查询,其中列表是 Invoices 集合中的时间线_rowids,这导致某些时间线仍然不是找到了。

提前感谢您的帮助!

【问题讨论】:

    标签: php mysql laravel-4 eloquent eager-loading


    【解决方案1】:

    好的。我想我从根本上误解了人际关系的运作方式。因为它们是在模型已经实例化之后加载的,所以关系查询的 where 部分的数组是通过访问模型的属性来构建的。一旦我发现,这实际上是一个简单的解决方法。

    我写了这个函数,它根据关系返回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');
    }
    

    我希望这对其他人有所帮助。搞砸了我一段时间!

    【讨论】:

      猜你喜欢
      • 2019-07-08
      • 1970-01-01
      • 1970-01-01
      • 2021-03-10
      • 2021-10-19
      • 2021-10-09
      • 2021-08-30
      • 2015-11-25
      • 2014-11-30
      相关资源
      最近更新 更多