如何使用Rails Arel构建查询时间戳距今满指定时长的SQL语句
正确Arel实现写法
写法1:手动构造NOW()函数节点
你需要先通过Arel的命名函数节点构造原生NOW(),再执行字段间的运算,完整代码如下:
t = SomeTable.arel_table # 构造SQL原生NOW()函数节点 now_func = Arel::Nodes::NamedFunction.new('NOW', []) # 拼接查询条件:updated_at < NOW() - some_durations query = t.project(Arel.star).where( t[:updated_at].lt(now_func - t[:some_durations]) )
执行query.to_sql即可验证生成的SQL和你预期的目标语句完全一致。
写法2:跨数据库兼容写法
如果需要适配PostgreSQL、MySQL等不同数据库的当前时间语法,可以直接用Arel内置的当前时间节点,无需手动写函数名:
t = SomeTable.arel_table query = t.project(Arel.star).where( t[:updated_at].lt(Arel::Nodes::CurrentTime.new - t[:some_durations]) )
Rails ActiveRecord 结合用法
如果你是在Rails项目中使用,不需要手动调用project查全量字段,直接把Arel条件传给ActiveRecord的where方法即可:
t = SomeTable.arel_table result = SomeTable.where( t[:updated_at].lt(Arel::Nodes::CurrentTime.new - t[:some_durations]) )
注意:你原有写法的两处问题:
- 缺少当前时间节点的构造,直接用时间字段和时长字段比较不符合逻辑
- 误用了
created_at字段,需要和目标SQL一致改为updated_at
内容的提问来源于stack exchange,提问作者Chi
相关产品推荐
相关产品推荐

