如何为Rails Activerecords可靠地比较created_at

时间:2013-07-17 20:54:40

标签: ruby-on-rails activerecord timestamp

基本上,我的查询是说记录的created_at大于它自己的created_at。

irb(main):025:0> u = User.first

User Load (1.0ms)  SELECT "users".* FROM "users" LIMIT 1
=> #<User id: 1, email: "my@email.com", encrypted_password: "stuff...", created_at:
"2012-02-01 18:56:45", updated_at: "2012-03-17 21:10:13">

irb(main):026:0> User.where("created_at > ?", u.created_at).include? u

User Load (1.0ms)  SELECT "users".* FROM "users" WHERE (created_at > '2012-02-
01 18:56:45.740392')
=> true

显示的查询清楚地表明它是一个日期时间格式化问题...当它构建查询时,它会舍入一小段时间。 我是否可以修改查询以按可预测/一致的方式按顺序对其进行排序?

我讨论了一些讨论ActiveRecord精度的其他问题,并建议使用strftime等,但我无法让它可靠地工作。我正在使用开发中的SQLite(我的控制台报价)和Postgres的生产。

注意:此处更广泛的目标是将#next#previous methods添加到我的大部分/全部资源中,以便我可以在管理菜单中更轻松地迭代它们。如果有另一种方法来实现可靠的默认订单,我会对它开放。

当我传递非:name之类的非时间戳参数时,这两种方法都可以正常编码,但如果我没有传递任何参数,则#next会返回相同的对象(默认为:created_at

def previous(column = :created_at)
 self.class.first(:conditions => ["#{column} < ?", self.send(column)], :order => "#{column} desc")
end

def next(column = :created_at)
 self.class.first(:conditions => ["#{column} > ?", self.send(column)], :order => "#{column} asc")
end

2 个答案:

答案 0 :(得分:1)

对于那种情况,你应该只使用id并且不要担心日期(无论如何它都会或多或少地起作用)。它是自然排序,索引等。

def previous(column = :id)
  self.class.first(:conditions => ["#{column} < ?", self.send(column)], :order => "#{column} desc")
end

def next(column = :id)
  self.class.first(:conditions => ["#{column} > ?", self.send(column)], :order => "#{column} asc")
end

答案 1 :(得分:0)

这将解决我关于跳过具有相同值的记录的评论。

def previous(column = :id)
 self.class.first(:conditions => ["#{column} = ? AND id < ?", self.send(column), self.id], :order => 'id desc') ||
  self.class.first(:conditions => ["#{column} < ?", self.send(column)], :order => "#{column} desc")     
end

def next(column = :id)
 self.class.first(:conditions => ["#{column} = ? AND id > ?", self.send(column), self.id], :order => 'id asc') ||
  self.class.first(:conditions => ["#{column} > ?", self.send(column)], :order => "#{column} asc")
end