Rails中基于字符串start_time查询近两月未取消活动的ActiveRecord语法问题
正确的ActiveRecord查询写法
你的需求是筛选本月和上月且rained_out = false的活动,由于start_time存储为YYYY-MM-DD格式的字符串,不能直接用Ruby的字符串方法在SQL查询里,得用数据库对应的字符串处理函数。
核心思路
直接匹配start_time的前7位(即YYYY-MM格式),这样能精准覆盖整月的日期,还能处理跨年场景(比如1月的上月是去年12月)。
步骤1:计算当前月和上月的YYYY-MM字符串
先获取正确的年月值,处理跨年情况:
current_year = Time.now.year current_month = Time.now.month last_month_year, last_month = if current_month == 1 [current_year - 1, 12] else [current_year, current_month - 1] end current_month_str = "#{current_year}-#{sprintf("%02d", current_month)}" last_month_str = "#{last_month_year}-#{sprintf("%02d", last_month)}"
步骤2:根据数据库类型编写查询
MySQL/SQLite 版本
使用SUBSTR函数截取前7位:
Event.where(rained_out: false) .where("SUBSTR(start_time, 1, 7) IN (?, ?)", current_month_str, last_month_str)
PostgreSQL 版本
可以用LEFT函数更简洁:
Event.where(rained_out: false) .where("LEFT(start_time, 7) IN (?, ?)", current_month_str, last_month_str)
为什么你的原写法报错?
你在where里写的是SQL语句,不是Ruby代码,所以start_time[5,2].to_i这种Ruby语法在SQL里不生效,必须替换成数据库支持的字符串处理函数。另外,你原来的Ruby逻辑存在优先级问题,正确的逻辑应该是(本月 OR 上月) AND rained_out = false,而非你写的混乱条件组合。
内容的提问来源于stack exchange,提问作者daveasdf_2
相关产品推荐
相关产品推荐

