6

我有時區和postgresql數據庫的問題(Rails 3.0.4,PostgreSQL 9.0)。我正在使用自定義作用域,在其中添加了一些條件,並加入了等。Rails不轉換時區(PostgreSQL)

問題是,Rails不會將時間轉換爲我的本地時區。 這裏是範圍的代碼:

scope :with_activities_within_range_in_week, lambda{ |latMin, lngMin, latMax, lngMax, date| 
    select("date_trunc('day', activities.starting_at) as date, 
     count(activities.id) as value 
    ") \ 
    .within(latMin, lngMin, latMax, lngMax) \ 
    .joins(:activities) \ 
    .merge(Activity.in_week(date)) \ 
    .group("date") \ 
    .order("date") 
    } 

的爲範圍的方法檢查中,該Activity.in_week範圍返回此:

where("activities.starting_at >= ? AND activities.starting_at < ?", start, stop) 

而且在select語句,我想TRUNC的starting_at現場到日。

我得到的日期字段以下的輸出:

2011-04-07 18:48:32 
2011-04-02 14:07:20 
2011-04-02 14:06:49 

遺憾的是它不包括時區。當我嘗試通過「正常」Rails功能訪問我的模型時,它的工作原理如下:

puts Activity.first.starting_at 
-> 2011-04-15 06:47:55 +0200 

我在做什麼錯了?希望有人能幫助!

THX, 禮服

+0

數據庫內部的'activities.starting_at'類型是什麼?如果你從'psql'中選擇'starts_at from activities',會發生什麼? – 2011-04-20 23:42:23

+0

'activities.starting_at'是'沒有時區的時間戳'(存儲在utc中)。 '從活動中選擇starting_at返回'2011-04-15 04:47:34',也沒有時區。但是不應該將時間轉換爲具體時區?用我的問題'放置Activity.first.starting_at - > 2011-04-15 06:47:55 + 0200'的例子,它的工作原理。 – 23tux 2011-04-21 07:52:51

+0

我發現另一個有趣的事情:當我嘗試迭代結果,並轉儲我的日期字段的類,我得到'字符串'。但它應該是'ActiveSupport :: TimeWithZone'。我讀了postgresql的文檔,'date_trunc('day',activities.starting_at)'應該返回'timestamp'。爲什麼Rails沒有轉換這個? – 23tux 2011-04-21 08:07:52

回答

5

您的數據庫存儲在UTC的時間戳(因爲它應該)。 ActiveRecord在知道它有時間戳時正在進行時區調整;所以,當你這樣說:

puts Activity.first.starting_at 

AR知道starting_at是一個時間戳,因此實例的時間戳爲ActiveSupport::TimeWithZone實例和類應用時區調整。但是,當你這樣說:

select("date_trunc('day', activities.starting_at) as date ... 

AR不會解析SQL弄清楚,date_trunc會返回一個時間戳,AR甚至不知道什麼date_trunc手段。 AR只會看到一個從數據庫中出來的字符串,它會在沒有解釋的情況下將它傳給你。您可以自由地將該字符串自動填充到ActiveSupport::TimeWithZone(或您最喜歡的時間處理類):告訴AR事件它沒有並且不能單獨知道是沒有錯誤的。

Rails很聰明,但它並不神奇。

+0

thx爲您的答案。那是因爲我傾倒了班級。你如何將字符串提供給'ActiveSupport :: TimeWithZone''?迭代結果並轉換字符串? – 23tux 2011-04-21 08:20:05

+0

無論如何,你將會遍歷結果,所以你可以把TimeWithZone的東西放在那裏。我不是一名AR3範疇專家,但可能會有更好的方法。 – 2011-04-21 08:24:58