2011-06-04 89 views
1

我已經閱讀了不少文章,完成了我的作業。我有存儲爲UTC所有時間,每個用戶設置自己的時區,等等。這裏是我遇到的問題:Activerecord:在當地時間將字符串轉換爲時間

Time.zone 
=> GMT-05:00 Eastern Time US Canada 

t = Ticket.first 
t.hold_until = "Jan 1, 2012 9:00PM" 
t.save! 

t.hold_until 
=> Sun, 01 Jan 2012 16:00:00 EST -05:00 

# notice the above time lost 5 hours 

的問題是,字符串是由用戶提供的POST請求。假設用戶輸入是在他們的本地時間,而不是UTC。我錯過了什麼,或者不應該是ActiveRecord默認?除了必須在我的所有控制器中轉換時間之外,什麼是正確的方法。這似乎是錯誤的,而不是非常乾燥。

回答

0

我想出了這個問題,它與ActiveRecord中寫得不好的代碼有關(驚喜!)。無論如何,ActiveRecord :: Base.define_attribute_methods通過缺少方法被懶惰地調用。我有這樣的方法定義如下:

def hold_until=(value) 
    # do some stuff here 
    super 
end 

所以ActiveRecord跳過那種認爲它被定義的方法。它應該沒有關係,但由於它的設計不佳。 AR有多種不同的方式來根據列類型定義方法。調用超級方面的步驟,並進入一般的「write_attribute」調用。唯一的解決辦法是自己轉換時間。在包含模塊之前,您無法調用define_attribute_methods,因爲所有alias_method_chain廢話。而且你不能利用他們已經編寫的代碼,因爲它在class_eval塊中。如果可能的話,我會推薦datamapper。