ruby-on-rails - ActiveRecord 在日期字段上按年、日或月查找

标签 ruby-on-rails ruby-on-rails-3 activerecord rails-activerecord

我有一个具有日期属性的 ActiveRecord 模型。是否可以利用该日期属性按年、日和月查找:

Model.find_by_year(2012)
Model.find_by_month(12)
Model.find_by_day(1)

或者是否可以简单地find_by_date(2012-12-1)。

我希望能够避免创建年、月和日属性。

最佳答案

假设您的“日期属性”是一个日期(而不是完整的时间戳),那么一个简单的 where 将为您提供“按日期查找”:

Model.where(:date_column => date)

您不需要find_by_date_column,因为这最多会给出一个结果。

对于年、月、日查询,您希望使用extract SQL 函数:

Model.where('extract(year  from date_column) = ?', desired_year)
Model.where('extract(month from date_column) = ?', desired_month)
Model.where('extract(day   from date_column) = ?', desired_day_of_month)

但是,如果您使用 SQLite,则必须使用 strftime,因为它不知道 extract 是什么:

Model.where("cast(strftime('%Y', date_column) as int) = ?", desired_year)
Model.where("cast(strftime('%m', date_column) as int) = ?", desired_month)
Model.where("cast(strftime('%d', date_column) as int) = ?", desired_day_of_month)

%m%d 格式说明符在某些情况下会添加前导零,这可能会混淆相等性测试,因此 cast(... as int) 将格式化字符串强制转换为数字。

ActiveRecord 不会保护您免受数据库之间的所有差异的影响,因此一旦您做了任何不平凡的事情,您要么必须构建自己的可移植层(丑陋但有时是必要的),要么将自己与一组有限的数据库联系起来(现实,除非您要发布必须在任何数据库上运行的东西),或者在 Ruby 中执行所有逻辑(对于任何非平凡的数据量来说都是疯狂的)。

在大型表上,年、月和日查询会非常慢。有些数据库允许你在函数结果上添加索引,但 ActiveRecord 太笨了,无法理解它们,所以如果你尝试使用它们,会弄得一团糟;因此,如果您发现这些查询太慢,那么您必须添加您试图避免的三个额外列。

如果您要经常使用这些查询,那么您可以为它们添加范围,但 recommended way to add a scope with an argument只是添加一个类方法:

Using a class method is the preferred way to accept arguments for scopes. These methods will still be accessible on the association objects...

所以你会有如下所示的类方法:

def self.by_year(year)
    where('extract(year from date_column) = ?', year)
end
# etc.

关于ruby-on-rails - ActiveRecord 在日期字段上按年、日或月查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9624601/

相关文章:

ruby-on-rails - 从 postgresql 函数中选择 ActiveRecord 连接

ruby-on-rails - Arel:如何使用 OR 干净地连接多个条件?

ruby-on-rails - 使用书面记录,了解与 object_changes 的区别?

ruby-on-rails - Rails 3 中的自引用模型

javascript - 在 Rails 应用程序中改进不显眼的 javascript(并可能使用 CoffeeScript)

ruby-on-rails - 处理 2 个模型之间的 4 种关系的最佳方法是什么?

html - 更改 Html.erb 中 Ruby 变量的值

ruby-on-rails - Rails 2.3.5 连接到 SQL Server 2005

ruby - ActiveRecord 需要 ruby​​ 版本 >= 2.2.2

ruby-on-rails - Capistrano 冷启动 - git :check 的问题