在Rails中如何使用scope筛选Task模型中今日到期的任务
问题原因
- 你的
duedate字段是datetime类型,存储带时分秒的完整时间,而Date.now返回仅包含日期的日期对象,直接用等号匹配只会命中截止时间恰好是当日0点0分0秒的任务,其余当日到期的任务都会被过滤掉。 due_today?实例方法存在语法错误,你写的是赋值语句duedate = Date.now,而非等价判断==,方法返回值永远为当前日期,逻辑完全失效。- 直接使用
Time.now/Date.now读取的是服务器系统时区,和Rails项目配置的时区可能不一致,容易出现日期偏移的问题。
修正后代码
class Task < ApplicationRecord # 过期任务:未完成且截止时间早于当前时间,不需要过滤已完成可删除where(completed: false) scope :overdue, -> { where(completed: false).where("duedate < ?", Time.current) } # 今日到期:截止时间落在当日0点到次日0点的区间内 scope :due_today, -> { where(duedate: Date.current.all_day) } def overdue? !completed? && duedate < Time.current end def due_today? duedate.to_date == Date.current end end
补充说明
Date.current.all_day是Rails提供的语法糖,会自动生成当日完整的时间区间,传入where方法后会自动生成区间匹配的SQL语句,完美适配datetime类型的字段查询。所有时间改用current系列方法,会自动读取Rails项目配置的时区,避免时区不一致导致的日期判断错误。
内容的提问来源于stack exchange,提问作者Joshua
相关产品推荐
相关产品推荐

