如何通过Rails ActiveRecord获取今天创建的记录?

128

如果我想获取所有今天创建的记录,应该如何编写条件语句?

10个回答

254
Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)

PS:这个答案已经被修改,因为Harish Shetty的答案比我的更好。由于我的答案被接受了,我已经更新了这个答案以得到社区的支持。


8
在最新版本中,这可以通过Post.where(created_at: Time.current.all_day)更加简化。 - Eyeslandic

130

我知道这个问题有一个被接受的答案。然而,被接受的答案中提到的解决方案可能会在表格大小增长时导致性能问题。

通常情况下,如果你基于 created_at 列进行查询,需要在迁移文件中为表格添加索引。

add_index :posts, :created_at

现在,要查找今天创建的记录:
Rails 3/4
Post.where("created_at >= ?", Time.zone.now.beginning_of_day)

查找某一天创建的帖子。
Post.where(:created_at => (date.beginning_of_day..date.end_of_day))

在您的模型中添加一个静态方法

class Post < ActiveRecord::Base
  def self.today
    where("created_at >= ?", Time.zone.now.beginning_of_day)
  end
end

Post.today #returns posts today

Rails 2

Post.all(:conditions => ["created_at >= ?", Time.zone.now.beginning_of_day])

为您的模型添加一个命名作用域

class Post < ActiveRecord::Base    
  named_scope :today, lambda { 
    {
      :conditions => ["created_at >= ?", Time.zone.now.beginning_of_day]
    }
  }
end

Post.today #returns posts today

1
关于索引的观点很好。只想澄清一下,这篇文章中的 scope 示例仅适用于 Rails 3,因为它似乎在 Rails 2 标题下。在 Rails 2 中,您需要使用 named_scope 而不是 scope。此外,在 Rails 3 中,您可以等效地使用类方法def self.today where("created_at >= ?", Time.now.beginning_of_day) end在这种情况下,这可能比使用作用域更清晰,因为它允许您放弃 lambda。 - evanrmurphy
@evanrmurphy 你能/应该把你的评论从“仅限Rails 3”修改为“Rails 3及以上”吗? - kaichanvong
@kaichanvong 我不熟悉Rails 4,所以我想说“Rails 3(及更高版本)”,但是SO不允许我编辑评论 :-/ - evanrmurphy

34

Rails 5.1有一个all_day助手函数,在这里非常有用。

Post.where(created_at: Date.today.all_day)
或者
Post.where(created_at: Date.parse("YYYY-MM-DD").all_day)

31

MySQL:

Model.all :condition => ["DATE(created_at) = ?", Date.today] # rails 2
Model.where("DATE(created_at) = ?", Date.today) # rails 3

PostgreSQL:

Model.all :condition => ["created_at::date = ?", Date.today] # rails 2
Model.where("created_at::date = ?", Date.today) # rails 3

20

为 Rails3 改编的 Mohit Jain 的答案

Model.where "DATE(created_at) = DATE(?)", Time.now

9

Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)

这将在table_name中添加“namescopes”属性。


5

model.rb

scope :posted_today, -> { posted_between_period(Time.now.midnight, Time.now.end_of_day) }

posts_controller.rb

Post.posted_today

3
@Pathiv,“between_period”听起来很有趣。我没有找到任何相关文档,你能提供一些链接吗?Rails如何选择用于比较的列? - Harish Shetty

1

由于某种原因,此帖子中的其他解决方案以及StackOverflow上的其他解决方案都无法在我的Postgres数据库中使用(使用Rails 4.2.4和Ruby 2.2.3p173)。这是我唯一能够使查询工作的查询:

Post.where("created_at >= TIMESTAMP 'now'")

-1

查询从今天起创建的记录

使用arel作用域

class Post < ActiveRecord::Base    
  scope :create_from_today, -> {
    where(arel_table[:created_at].gteq(Time.zone.now.beginning_of_day))
  }
end

然后我们可以使用它

today_posts = Post.created_from_today

where('created_at >= now()') 只会找到创建时间在未来的项目。 - Paul Danelli
是的,我会从答案中删除它,发现得好,谢谢。 - Hieu Pham
你现在面临的问题是,标记有未来日期的记录将被呈现出来,同时也会呈现今天的记录。如果你想避免使用between,你还应该指定.lteq(Time.zone.now.end_of_day)) - Paul Danelli

-5
在rails 4.2.3中,如果想要获取今天创建的记录,并使用mysql,请使用以下代码。 @usergoals = Goal.where("userid = :userid and Date(created_at) = :date", { userid: params[:id], date: Date.today }) 在这里我使用了多个条件,如果您愿意,可以将其编辑为单个条件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接