2010-08-19 2 views
1

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

Update

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

Спасибо!

ответ

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


На основе вашего обновления, я бы все равно не изменится, как 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) | 
+----------+------------+-----------------------------------------------------------------+ 
+0

Я не упомянул об этом, но причина, почему я хочу делать то, что я спросил, потому что я хотел бы, чтобы отсортировать данные, по дате с часами и секундами. Конечно, я мог форматировать дату в своем избранном, но я не думаю, что это было бы хорошим решением. – spacemonkey

+0

, но как насчет производительности при использовании sql-функций при запросе данных?Поскольку эти данные будут действительно часто запрашиваться, а очень реже обновляться – spacemonkey

+0

Вам придется пройти через некоторое время, чтобы изменить, как «updated_at» хранится, потому что, даже если вы попытаетесь установить его вручную, Rails будет автоматически задайте значение, которое оно хочет, когда оно идет, чтобы сохранить запись. –

1

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

1

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

0

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

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

В хелперов файле:

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

Я бы порекомендовал решение Даниэля. Однако, если вы набрали 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 
Смежные вопросы