覆盖Rails updated_at属性

时间:2010-08-19 21:05:04

标签: ruby-on-rails timestamp override attributes

我想修改 updated_at 属性,以便每次更新记录时,它只会显示日期和小时,而小时和分钟则为零。 而不是2010-08-13 11:04:12,会有2010-08-13 11:00:00 。在Rails 2.3中最合理的方法是什么?

更新

我之所以要做我所要求的是因为我想按日期排序数据,省略了小时和秒。

谢谢!

5 个答案:

答案 0 :(得分:4)

不要尝试更改存储在数据库中的值;改变输出方式:

timestamp = @model.updated_at # where @model is your model object

# output it in a format that overrides the values for minute and second
puts timestamp.strftime "%Y-%m-%d %H:00:00"

有关您可以使用的其他格式说明符,请参阅strftime ruby​​ doc。


根据您的更新,我仍然不会更改updated_at的存储方式,而是在查询的ORDER BY内格式化日期。例如,你可以

ORDER BY DATE(updated_at), HOUR(updated_at), ...

我在我的应用程序中对实时表进行了非常快速的性能分析测试,该应用程序有大约22,000条记录。 ORDER BY updated_at需要在2.94到3.19之间完成,平均时间为3.00秒。 ORDER BY DATE(updated_at), HOUR(updated_at)需要2.93到3.06秒才能完成,平均时间为2.99秒。这是分析数据:

+----------+------------+-----------------------------------------------------------------+
| Query_ID | Duration   | Query                                                           |
+----------+------------+-----------------------------------------------------------------+
|        1 | 2.94530500 | SELECT * FROM posts ORDER BY updated_at                         |
|        2 | 2.94583800 | SELECT * FROM posts ORDER BY updated_at                         |
|        3 | 3.18711700 | SELECT * FROM posts ORDER BY updated_at                         |
|        4 | 2.96923700 | SELECT * FROM posts ORDER BY updated_at                         |
|        5 | 2.97255400 | SELECT * FROM posts ORDER BY updated_at                         |
|        6 | 3.06706800 | SELECT * FROM posts ORDER BY DATE(updated_at), HOUR(updated_at) |
|        7 | 3.00414400 | SELECT * FROM posts ORDER BY DATE(updated_at), HOUR(updated_at) |
|        8 | 2.95551500 | SELECT * FROM posts ORDER BY DATE(updated_at), HOUR(updated_at) |
|        9 | 3.02181900 | SELECT * FROM posts ORDER BY DATE(updated_at), HOUR(updated_at) |
|       10 | 2.93130000 | SELECT * FROM posts ORDER BY DATE(updated_at), HOUR(updated_at) |
+----------+------------+-----------------------------------------------------------------+

答案 1 :(得分:1)

这是一个时间戳对象,所以最好只使用辅助函数来截断最小/秒信息。

答案 2 :(得分:1)

whatever.created_at.strftime("%Y-%m-%d %H:00:00")

答案 3 :(得分:1)

我会推荐Daniel的解决方案。但是,如果您希望使用修改后的“updated_at”字段保存记录 100%肯定,则必须为给定模型重新实现rails的自动时间戳。

因此,在您的模型中,您可以执行以下操作:

self.record_timestamps = false # disables rails' auto-timestamping
before_create :set_created_at
before_save :set_updated_at  

def set_created_at
  self.created_at = Time.now
end
def set_updated_at
  self.updated_at = Time.now.change({:min => 0, :sec => 0}) # clears minutes and seconds
end

答案 4 :(得分:0)

这不是您应该对活动记录执行的操作。这是一个视图助手可以完成的事情,你不需要改变保存的方式,这可能只是将来更多的工作。

考虑strftime以及如何改变它。

在帮助文件中:

def format_date_for_rounded_hour(date)
    date.striftime("%Y-%m-%d %H:00")
end