gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 05:31:24 28 4
gpt4 key购买 nike

我有一个具有日期属性的 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/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com