Переопределить Rails атрибут updated_at - PullRequest
1 голос
/ 20 августа 2010

Я бы хотел изменить атрибут updated_at , чтобы при каждом обновлении записи в нем отображались только дата и часы, а часы и минуты были нулями. Вместо 2010-08-13 11:04:12 будет 2010-08-13 11: 00: 00 .Какой самый рациональный способ сделать это в Rails 2.3?

Обновление

Причина, по которой я хочу сделать то, что я просил, заключается в том, что я хочу отсортировать данные по дате с часамии секунды опущены.

Спасибо!

Ответы [ 5 ]

4 голосов
/ 20 августа 2010

Не пытайтесь изменить значение, хранящееся в базе данных; изменить способ вывода:

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 ​​для других спецификаторов формата, которые вы можете использовать.


Исходя из вашего обновления, я бы все равно не изменил способ хранения 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 голос
/ 20 августа 2010

Я бы порекомендовал решение Даниэля. Однако, если вы 100% положительны , что хотите сохранить запись с измененным полем «updated_at», вам придется заново реализовать автоматическую отметку времени для данной модели.

Итак, в вашей модели вы можете сделать следующее:

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
1 голос
/ 20 августа 2010

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

1 голос
/ 20 августа 2010

Это объект с отметкой времени, поэтому вам, вероятно, лучше всего использовать вспомогательную функцию для усечения информации мин / сек.

0 голосов
/ 20 августа 2010

Это не то, что вы должны делать с активной записью. Это то, что может сделать помощник по просмотру, и вам не нужно изменять способ сохранения вещей, что, вероятно, будет просто дополнительной работой в будущем.

Подумайте о strftime и о том, как вы можете изменить это вместо этого.

В файле помощника:

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