【问题标题】:Using a calculated value in a query scope with Eloquent在 Eloquent 的查询范围内使用计算值
【发布时间】:2016-04-19 03:17:20
【问题描述】:

我有两个 Eloquent 模型,CampLevel

Camp 有一个 start 和一个 end 日期字段。

Level 有一个 min_age 和一个 max_age 整数字段。

一个Level 与许多Camps 相关

使用查询范围和日期参数$dob,我想获取Camps 的集合,其中$dob 出生的人的年龄将在@ 上的min_agemax_age 之间987654336@日期。

换句话说(一些伪代码):

select * from Camps
   join Levels on Camps.level_id = Levels.id
where min_age <= (start - $dob)->toYears <= max_age

这样的事情是否可能使用查询范围,并且可能不使用任何原始查询?也许是这样?

public function scopeAgeAppropriate($query, $dob) {
    return $query->join('Levels', 'Camps.level_id', '=' ,'Levels.id')
                 ->where('min_age', '<=', start->diffInYears($dob))
                 ->where('max_age', '>=', start->diffInYears($dob));
}

【问题讨论】:

    标签: php laravel eloquent


    【解决方案1】:

    通过关系查询whereHas() 并使用TIMESTAMPDIFF 即时计算年龄:

    您的范围将是:

    public function scopeAgeAppropriate($query, $dob) {
        return $query->whereHas('levels',function($q) use ($dob) {
            return $q->where('min_age', '<=', \DB::raw("TIMESTAMPDIFF(YEAR, '{$dob}', Camps.start)"))
            ->where('max_age', '>=', \DB::raw("TIMESTAMPDIFF(YEAR, '{$dob}', Camps.start)"));
        })
    
    }
    

    【讨论】:

    • OP 在数据库上并不清楚,但我很确定 Postgres 适配器在获取模型时会运行 EXISTS 查询。这意味着Camps 将无法查询,除非我遗漏了什么?请告诉我
    • whereHas 使用子选择查询来检查关系,因此Camps 表将可供参考。
    • 当然可以。出于某种原因,我认为存在子查询无权访问父查询列。不知道我在想什么。
    • 这对我来说效果很好。我必须在 {$dob} 周围为 MySQL(我应该指定)添加单引号来接受查询。我希望有一个解决方案可以不使用原始查询和 Carbon 库来计算时间差,但这已经足够了。谢谢。
    猜你喜欢
    • 2015-06-13
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    相关资源
    最近更新 更多