Rails ActiveRecord date between
Rails 5.1引入了一个新的日期辅助方法all_day
,详情请见:https://github.com/rails/rails/pull/24930
>> Date.today.all_day => Wed, 26 Jul 2017 00:00:00 UTC +00:00..Wed, 26 Jul 2017 23:59:59 UTC +00:00
如果你正在使用Rails 5.1,查询语句将会是这样的:
Comment.where(created_at: _date.all_day)
太棒了。这实际上是ActiveSupport gem的一部分(随后也是整个ActiveRecord生态系统的一部分),所以它也可以在Rails之外工作!只需require 'active_record'
,然后你就可以使用了!
Rails ActiveRecord中的date between问题出现的原因是在查询某个时间段内创建的记录时,原始的写法不够清晰和可重用。为了解决这个问题,可以创建一个scope(作用域)来使代码更加可读和可重用。
在Comment.rb文件中,可以定义一个scope:
scope :created_between, lambda {|start_date, end_date| where("created_at >= ? AND created_at <= ?", start_date, end_date )}
然后可以使用created_between这个scope来查询指定时间范围内的记录:
Comment.created_between(1.year.ago, Time.now)
这种方法非常简洁,非常完美!我回来点赞这个答案,因为我在搜索这个问题时找到了它。我错误地猜测了语法,以为`#between?`接受一个范围(range)作为参数。
Rails ActiveRecord date between问题的出现的原因是Rails 3中原先接受的解决方法已经被弃用。解决方法是使用新的语法或者使用纯字符串条件。
在Rails 3中,应该使用以下语法来解决这个问题:
Comment.where(:created_at => _date.beginning_of_day.._date.end_of_day)
如果想要或者必须使用纯字符串条件,可以使用以下语法:
Comment.where('created_at BETWEEN ? AND ?', _date.beginning_of_day, _date.end_of_day)
另外,还可以使用范围对象来处理日期范围查询。在Rails中,范围对象只保存了下限和上限值,不会创建一个巨大的范围对象。例如,以下代码在irb中运行正常:1..1000000000000
还可以将日期范围查询封装成一个作用域(scope)。例如:
scope :between, -> (a, b) { where(created_at: a..b) }
对于今天的日期范围查询,可以使用以下语法:
User.where(created_at: DateTime.now.beginning_of_day..DateTime.now.end_of_day).count