You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails中使用ActiveRecord查询上月支出时无法获取31号数据的问题

Fix Missing 31st Day Data in Monthly Expenditure Query

Let's break down why you're missing the 31st day's data and how to fix it:

The Root Cause

When you use Date objects to query a datetime column (like created_at), Rails automatically converts the Date to a DateTime at midnight (00:00:00) of that date.

For example, if you're querying August 2020 in September, (Date.today.end_of_month) -1.month gives you the Date 2020-08-31, but it gets converted to 2020-08-31 00:00:00 in the query. That means your range only includes records up to August 30th 23:59:59 — any entries created on August 31st (with a time after midnight) fall outside the range.

Solution 1: Explicitly Cover the Full Last Day

Instead of relying on relative date math that cuts off the 31st, explicitly define the start and end of the previous month with full datetime coverage:

# Get the full datetime range for the previous month
prev_month_start = Date.today.prev_month.beginning_of_month.beginning_of_day
prev_month_end = Date.today.prev_month.end_of_month.end_of_day

# Run the query with the complete range
Expend.where(cc: "PUQ").where(created_at: prev_month_start..prev_month_end).sum(:total)

Solution 2: Use Rails' Built-in all_month Helper

Rails has a shortcut to handle this exact scenario. The all_month method returns a range from the first second of the month's start to the last second of the month's end, ensuring no days get cut off:

Expend.where(cc: "PUQ").where(created_at: Date.today.prev_month.all_month).sum(:total)

Why Your Original Code Failed

Let's unpack your original line for August 2020 (assuming today was September 2020):

(Date.today.beginning_of_month)-1.month # => 2020-08-01 (Date object)
(Date.today.end_of_month)-1.month # => 2020-08-31 (Date object)

When converted to datetime for the database query, this becomes 2020-08-01 00:00:00 to 2020-08-31 00:00:00. Any created_at timestamp on August 31st (like 2020-08-31 14:30:00) is after the end of your range, so it gets excluded.

Using end_of_day or all_month extends the range to 2020-08-31 23:59:59.999999, which captures every record from that day.


内容的提问来源于stack exchange,提问作者Poluxland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 09:18:15