2012-10-27 43 views
0

我發送了基於兩個表的Rails AREL查詢結果的json響應。響應包括兩個時間戳列:updated_at和updated_at_table_2。我重寫ActiveSupport :: TimeWithZone.as_json方法以獲取JSON所需的日期時間格式。同樣的方法在來自加入表的Rails 3 + Postgres + JSON時間戳列未調用ActiveSupport :: TimeWithZone.as_json

http://stackoverflow.com/questions/2937740/rails-dates-with-json 

我當前JSON響應被示出爲: { 「的updated_at」: 「2012年10月26日22時04分07秒-0400」, 「updated_at_table_2」:「2012-10 -27 02:04:07.463015「 }

我希望它們相同。我依靠下面的Rails代碼來生成json。

render :json => { :customer_order => @customer_order } 

其中@custoemr_order來源於:

CustomerOrder.select(%Q[ 
     updated_at, 
     c.updated_at as updated_at_table_2 
    ]). 
    joins(%{ as co inner join customers as c on (co.customer_id = c.id) 

問題:我怎麼能告訴Rails 3處理as_json爲updated_at_table_2作爲的updated_at列以同樣的方式?

任何建議/指針都很棒。

注:我發現這篇文章詢問有關同樣的根問題(雖然不是關於json)沒有好的解決方案。 :

http://stackoverflow.com/questions/12067173/rails-postgres-not-returning-timezone-info-on-column-from-joined-table 
+0

爲什麼不讓服務器以UTC的方式工作,向客戶端發送ISO 8601時間戳字符串,並讓客戶端應用需要的任何時區調整? –

+0

@ muistooshort同意!我希望我可以在瀏覽器客戶端使用Rails默認格式,如「2012-10-27 02:04:07.463015」。但是,Safari不會在Date對象中接受它,我需要在瀏覽器客戶端處理它(儘管Chrome工作正常)。我認爲在服務器端正確格式化時間戳字符串會更容易。 – GeorgeW

回答

1

如果你看一下您的查詢給你,你會清楚地看到你要去哪裏錯了:

> o = CustomerOrder.select(%Q[ ... ]).joins(...) 
> puts o.updated_at.class 
=> ActiveSupport::TimeWithZone 
> puts o.updated_at_table_2.class 
=> String 

的ActiveRecord沒有專門的辦法應該是什麼樣的事情updated_at_table_2這樣它會將其保留爲一個字符串,並且您的to_json猴子補丁將不會應用於字符串。

如果你想用你的to_json猴補丁(我認爲這是一個壞主意)保持,那麼你需要手動轉換updated_at_table_2一個ActiveSupport::TimeWithZone像這樣的東西:

x = ActiveSupport::TimeWithZone.new(
    Time.parse(o.updated_at_table_2), 
    Time.zone 
) 
# x is now an ActiveSupport::TimeWithZone 

或者,你可以加載關聯的對象並在其上調用updated_at

我會盡量放棄整個方法:讓服務器專門以UTC工作,以ISO-8601格式發送客戶端時間戳,並讓客戶端應用本地時區。

+0

有沒有辦法告訴Rails將時間戳列轉換爲一致格式的字符串?無論時間戳列是否來自連接表。 – GeorgeW

+0

我打算使用UTC,但想要使用一致的日期時間字符串,我可以在將「-0000」附加到javascript Date對象後傳遞給它。然而,Safari正在給我帶來問題。我有很多JSON結果通過AREL查詢通過多個表的聯接發送回客戶端。這就是爲什麼我尋找一個簡單的配置更改或重寫一次as_json方法一次。 – GeorgeW

+0

問題是,Rails不知道你有一個時間戳,它只是看到一個字符串。第一個是你模型中的一列,所以Rails知道它是什麼。我仍然使用ISO 8601格式,並在客戶端添加一些解析JavaScript,手工拆分ISO 8601是微不足道的。 –