【问题标题】:Rails: Find what is the Oldest Item in a TableRails:查找表中最旧的项目
【发布时间】:2015-08-28 21:57:23
【问题描述】:

我正在尝试找到一种方法来获取最旧的 created_at 值以获取类中最旧的对象,以便以后可以对其进行操作。

我正在尝试将所有项目添加到数组中,然后获取最旧的值,然后使用 .where 活动记录方法将其转换回来以获取在该日期创建的对象。

这是我目前所拥有的:

date_array=[]
      buy_requests.each do |buy_request|
        date_array << buy_request.created_at
      end
      date_array.min

但我觉得有更简单的方法可以做到这一点。

我遇到的一个问题是,当我将日期添加到数组时,我不再拥有创建它的时间,因此一旦我使用 .min 获得最旧的日期,我就不能再使用 .where。

谢谢。如果我不够清楚,请告诉我。

【问题讨论】:

    标签: ruby-on-rails datetime activerecord


    【解决方案1】:

    不需要先获取最早的时间戳再获取对应的对象,简单:

    BuyRequests.order(:created_at).limit(1)
    

    ...这将受益于 created_at 上的索引,或者可能...

    BuyRequests.first
    

    ...如果您的 ID 以先到先得的顺序可靠分配。

    您可能希望通过以下方式打破相等的 created_at 时间戳:

    BuyRequests.order(:created_at, :id).limit(1)
    

    【讨论】:

    • 前两个解决方案推断出很多信息,不是吗?第一个是一个非常好的解决方案,但我觉得它在 OP 的问题之外假设了很多。第二种解决方案绝对危险,因为它完全取决于数据库中主键的逻辑顺序,我们知道这并不总是发生在不同的 Rails 变体之间。
    • 是的,我同意 ".first" 方法——我的记忆可能错了,但我认为在 Rails 3 的一个子版本中,首先对 PostgreSQL 查询应用了限制 (1)没有任何订购。此外,如果您使用像 Oracle RAC 或 Exadata 这样的多实例数据库,那么每个实例可能都有自己的序列号池,那么最低的不一定是第一个。如果您使用 UUID 作为主键,坦率地说,我不确定首先要做什么。
    • 我认为就 OP 的一般问题而言,了解这里正在解决什么问题会有所帮助。识别表中的第一条记录本身就是一个简单的技术问题,但我确实想知道它背后的目的是什么。
    【解决方案2】:

    min_by 方法完全符合您的要求:

    buy_requests.min_by(&:created_at)
    

    但是,除非您无论如何都需要加载请求,否则让数据库进行排序(假设这是一个活动记录模型)通常会更有效,方法是执行类似的操作

    ByRequest.order('created_at asc').first
    

    【讨论】:

      【解决方案3】:

      您可以非常轻松地使用 Ruby 的 sort_by 方法。

      objects.sort_by { |obj| obj.attribute }
      

      因此,对于您的示例,它将是:

      buy_requests.sort_by { |req| req.created_at }
      

      【讨论】:

      • 将使最旧的项目成为数组中最后一个项目的第一个吗?如果 sort_by 确实创建了一个数组。
      • 正确。最早的项目将是“最旧的”。
      • 所以要获取首先创建的对象,我会这样做:buy_requests.sort_by { |req| req.created_at }[0]
      • buy_requests.sort_by { |req| req.created_at }.first
      • 查看原始问题:“...然后使用 .where 活动记录方法将其转换回来,以获取在该日期创建的对象。”我的回答是正确的,因为 OP 正在尝试获取有问题的对象,而不仅仅是 created_at 属性。
      【解决方案4】:

      如果您只关心最旧的created_at 对象,为什么不在模型上使用#first 方法。我假设id 是按顺序生成的。即1, 2, 3, 4

      buy_requests.first
      

      将为您提供您拥有的最早的 BuyRequest 实例。我假设对象 BuyReuest 是一个 ActiveRecord 对象

      【讨论】:

      • 这很危险,因为根据您的 Rails 版本(例如 Rails 3)与其他当前(或未来)版本的 Rails,此方法可能无法通过主 ID 查询:apidock.com/rails/ActiveRecord/FinderMethods/first To要防故障,你仍然需要做Model.order(:attribute).first,这违背了这个答案的目的。
      猜你喜欢
      • 2014-08-15
      • 2014-05-28
      • 1970-01-01
      • 2010-10-24
      • 2011-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-06
      相关资源
      最近更新 更多