【问题标题】:Active Record - Find records which were created_at before todayActive Record - 查找今天之前创建的记录
【发布时间】:2011-12-20 03:38:20
【问题描述】:

我想获取 created_at 字段小于今天(日期)的所有记录。 有没有类似的东西:

MyTable.find_by_created_at(< 2.days.ago)

【问题讨论】:

    标签: ruby activerecord


    【解决方案1】:

    使用ActiveRecord标准方式:

    MyModel.where("created_at < ?", 2.days.ago)
    

    使用底层Arel接口:

    MyModel.where(MyModel.arel_table[:created_at].lt(2.days.ago))
    

    在 Arel 上使用一些 thin layer

    MyModel.where(MyModel[:created_at] < 2.days.ago)
    

    使用squeel

    MyModel.where { created_at < 2.days.ago }
    

    【讨论】:

    • 谢谢!。如果我需要 MyTable1 中的所有记录,这与 MyTable 在相同条件下是一对一的关系,如何编写查询?我指的是MyTable1.where(MyTable[:created_at] &lt; Time.now) 这样的东西有可能吗?
    • 是的,我已经设置了关系活动记录类。
    【解决方案2】:

    Time.now 指的是现在或这一秒。因此,现在要查找所有用户,只需使用

    @users = User.all
    

    这将找到现在之前的所有用户,并将排除未来的用户或在 Time.now 之后加入的用户

    【讨论】:

    • Time.now 与 Today 不同
    【解决方案3】:

    另一种方法是使用Arel 接口在MyModelApplicationRecord 中创建一个范围,如tokland sugensted 在his answer 中,如下所示:

    scope :col, ->(column, predication, *args) { where(arel_table[column].public_send(predication, *args)) }
    

    范围的使用示例:

    MyModel.col(:created_at, :lt, 2.days.ago)
    

    对于所有谓词,请检查documentationsource code。此范围不会破坏where 链。这意味着您还可以:

    MyModel.custom_scope1.col(:created_at, :lt, 2.days.ago).col(:updated_at, :gt, 2.days.ago).custom_scope2
    

    【讨论】:

    • 好主意。但是,ActiveRecord::Relation 定义了一个名为 arel 的实例方法,这意味着您只需选择一个不同的名称。
    【解决方案4】:

    要获取截至 2 天前创建的 MyTable 的所有记录:

    MyTable.where(created_at: Date.new..2.days.ago)
    

    请注意,您还可以通过类似的方式查找字段包含将来字段的记录,即从现在起至少 2 天后获取 MyTableevent_date 的所有记录:

    MyTable.where(event_date: 2.days.from_now..DateTime::Infinity.new)
    

    【讨论】:

    • 这会产生"created_at" BETWEEN $1 AND $2 [["created_at", "4713-01-01 BC"], ["created_at", "2020-03-31 21:43:28.113759"]]