0

我有一个模型 Product,它既有:created_at时间戳又有:expiration_in_days属性。产品在创建后的特定天数被视为过期。如何编写只返回未过期产品的查询?

导轨 4,红宝石 2.1,PG 0.17

我一直在尝试这样的查询,但没有成功:

#product.rb
def self.not_expired
  where('created_at + expiration_in_days * 86400 >= ?', Time.now)
end

我有一个运行良好的纯 Ruby 版本,只是速度较慢:

#product.rb
def self.not_expired
  select{ |p| (p.created_at.to_i + p.expiration_in_days * 86400) >= Time.now.to_i}
end
  • 注意,86400 计算将 :expiration_in_days 整数转换为秒

任何关于比文档 ( http://guides.rubyonrails.org/active_record_querying.html )更高级的 Rails 查询的指针也将受到欢迎。

提前致谢。

4

3 回答 3

1

试试这个:

def self.not_expired
  where("created_at + (expiration_in_days * 86400)::text::interval >= ?", Time.now)
end

更新:添加参考

您可以在此处了解有关日期和时间功能的更多信息。

鉴于您的情况有特殊要求,即 的值expiration_in_days是表中的一列,我们不能使用created_at + interval expiration_in_days day. 相反,我们需要将其值类型interval转换为. 但是您不能直接将类型转换为整数,这就是我们text首先将其转换为的原因。

于 2014-08-05T22:26:40.727 回答
0

如果 A <= C - B,则 A + B > C 为真

因此,与其尝试将过期时间添加到 created_at,不如从 Time.now 中减去过期时间。

def expiration_threshold
  Time.now - amount_of_time # I'm not sure what type to use
end

def self.not_expired
  where( "created_at > ? ", expiration_threshold )
end

在处理各种日期/时间时,我一直对 Rails/Ruby 需要什么类型感到有点困惑,你可能不得不玩弄。

于 2014-08-05T22:23:03.493 回答
0

我不确定这是否可行,但尝试这样的事情

def self.not_expired
  where("TIMESTAMP created_at + INTERVAL '1 day' * expiration_in_days >= NOW()")
end
于 2014-08-05T22:33:40.763 回答