Laravel - 来自whereHas()

时间:2016-04-08 12:18:33

标签: laravel eloquent relationship

这是我在这里的第一篇文章,所以请原谅任何错误:)

我目前正在从事库存管理应用项目(Laravel)。我发现我做的任何事情都没有用,所以现在我求求它。

我有一张包含产品的表格,其中一些与其他产品有关系。一切都发生在一张桌子上。如果产品有孩子,则孩子会覆盖父母。

products table view

然后,我在其上运行的所有查询都使用以下逻辑:

  • 如果该项目没有任何孩子,请使用它。
  • 如果该项目有子项,请使用最新的子项(最高ID)

现在我在模型文件中创建了关系:

public function childItems(){
    return $this->hasMany('\App\OrderItem','parent_id');
}

public function parentItem(){
    return $this->belongsTo('\App\OrderItem','parent_id');
}

public function latestChild(){
    return $this->hasOne('\App\OrderItem','parent_id')->orderBy('id','desc')->limit(1);
}

latestChild()关系的问题是,当您运行此查询时:

\App\OrderItem::find(7)->latestChild()->get()

它工作正常并且只返回关系中的一条(最新)(id 6)记录 - 为此我必须添加orderBy并限制为hasOne()。

但是当我想在范围中使用这种关系时,所以在whereHas方法中,它没有正常工作,就像任何一个孩子而不是最新的孩子一样。

public function scopeDue($query){
    return $query->where(function($q){
                            $q->has('childItems','==',0)->has('parentItem','==',0)->whereDate('due_date','=', Carbon::today()->toDateString())->whereNull('return_date');
                        })->orWhere(function($q2){
                            $q2->has('childItems')->has('parentItem','==',0)->whereHas('childItems',function($q3) use($q2){
                                $q3->whereDate('due_date','=', Carbon::today()->toDateString())->whereNull('return_date');
                            });
                        })->with('latestChild');

}

但是,最后用()返回正确的记录。

我认为,它的工作原因是因为我的关系latestChild()返回所有子节点(尽管有hasOne()),当我在where中使用它时它忽略了我应用的过滤函数。

我知道它与我所描述的有点复杂,但为了更好地解释它,我会用一个例子。在修补程序中执行以下内容

\App\OrderItem::due()->get();

应该仅返回记录ID 2,因为数字7有子节点,当然id 5到期,但最新的子节点是id 6,这是未到期的。

我希望我已经解释得足以让你帮助我了,因为我已经疯了。 如果您对我如何通过改变现有的或改变其整体逻辑来实现我所需要的任何想法,请帮助!

谢谢, Darek

2 个答案:

答案 0 :(得分:0)

尝试这个:

->with(
    [
        'latestChild' => function (HasOne $query) {
            return $query->latest('id')->limit(1);
        }
    ]
);

答案 1 :(得分:-1)

我认为问题出在latestChild()方法中,您执行limit(1)。为什么不尝试使用last()方法?

所以:

public function latestChild(){
    return $this->hasOne('\App\OrderItem','parent_id')->last();
}

编辑:

如何返回这样的值:

public function latestChild(){
    $item = App\OrderItem::all()->last();
    return $item;
}