【问题标题】:How to compare created_at reliably for Rails Activerecords如何可靠地比较 Rails Activerecords 的 created_at
【发布时间】:2013-07-17 20:54:39
【问题描述】:

基本上,我的查询是说记录的 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

显示的查询清楚地表明这是一个日期时间格式问题......当它构建查询时,它会四舍五入一秒。 我可以修改查询以使其按 created_at 可预测/一致地排序吗?

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

注意:这里更广泛的目标是将#next#previous methods 添加到我的大部分/所有资源中,以便我可以在我的管理菜单中更轻松地遍历它们。如果有其他方法可以实现可靠的默认顺序,我愿意接受。

当我传递像:name 这样的非时间戳参数时,这两种方法都可以正常工作,但如果我不传递任何参数(默认为:created_at),#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

【问题讨论】:

  • 我也刚刚想到,如果您对多个记录具有相同值的属性进行排序,则此实现不会做得很好。按照编码,它将任意选择具有该值的记录之一,然后在遍历它们时跳过其他记录。

标签: ruby-on-rails activerecord timestamp


【解决方案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

【讨论】:

  • 是的,这显然是我一开始就应该走的路。谢谢。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    相关资源
    最近更新 更多