6

Zaman dilimi ve bir postgresql db (Rails 3.0.4, PostgreSQL 9.0) ile ilgili bir sorunum var. Bazı koşulları eklediğim özel bir kapsam kullanıyorum, vb.Raylar zaman dilimini dönüştürmez (PostgreSQL)

Sorun şu ki, Raylar zamanları yerel saat dilimime dönüştürmiyor.

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

Ve select deyiminde

, ben başlangıç'tan trunc istiyorum:

aralıkları için yöntem kontrolleri dahilinde
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 kapsamı bu döndürür: İşte kapsam kodudur güne alan.

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

Ne yazık ki dilimini içermez:

ben tarih alanı için aşağıdaki çıktıyı alıyorum. "Normal" Raylar işlevleriyle Modelimin erişmeye çalıştığınızda, çalışır: Ben yanlış yapıyorum ne

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

? Umarım birileri yardım edebilir!

thx

+0

Veritabanı içinde "activities.starting_at" türü ne tür? Ve 'psql' içinden aktivitelerden start_at'ı seçerseniz ne olur? –

+0

'activities.starting_at',' timezone' olmayan bir zaman damgasıdır (utc'de saklanır). 'aktiviteden start_atı seç ', bir zaman dilimi olmadan da' 2011-04-15 04: 47: 34' döndürür. Ancak, raylar zamanı belirli bir zaman dilimini anında mı çevirmemeli? Benim soru ile benim örneğim ile faaliyet koyar Activity.first.starting_at -> 2011-04-15 06:47:55 + 0200'. – 23tux

+0

Başka ilginç bir şey buldum: Sonuçları yinelemeyi denediğimde ve tarih alanımın sınıfını döktüğümde, ben String'i alıyorum. Ama 'ActiveSupport :: TimeWithZone' olmalıdır. Postgresql belgelerini okudum ve 'date_trunc ('day', activities.starting_at)' 'timestamp'ı döndürmelidir. Rails bunu neden dönüştürmez? – 23tux

cevap

5

Kişisel veritabanı (olması gerektiği gibi) UTC da damgalarını depoladığı smokini. ActiveRecord, bir zaman damgası olduğunu bildiğinde zaman dilimi ayarlamaları yapıyor; Eğer öyleyse, derken bu:

puts Activity.first.starting_at 

AR bir ActiveSupport::TimeWithZone örneği olarak zaman damgası başlatır ve o sınıf saat dilimi ayarlamasını uygular böylece starting_at bir zaman damgası olduğunu bilir. Bunu deyince de:

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

AR date_trunc bir zaman damgası döneceğini anlamaya SQL ayrıştırmak için gitmiyor, AR bile neyi date_trunc vasıta bilmiyor. AR sadece veritabanından çıkan bir ipi görecek ve yorumlamadan size teslim edecektir. Bu dizgiyi ActiveSupport::TimeWithZone (veya en sevdiğiniz zaman taşıma sınıfına) kendiniz beslemekte özgürsünüz: AR'nin kendi başına bilmediği ve bilmediği şeyleri anlatmak konusunda yanlış bir şey yoktur.

Raylar zekidir, ancak sihir değildir.

+0

thx. Sınıfı terk ederek bunu anladım. Dizeyi "ActiveSupport :: TimeWithZone" ile nasıl beslersiniz? Sonuçlar arasında yineleyin ve dizgeyi dönüştürün? – 23tux

+0

Yine de sonuçlarda yineleneceksiniz, böylece TimeWithZone malzemelerini oraya atabilirsiniz. Ben bir AR3 kapsamı guru değilim, bu yüzden daha iyi bir yol olabilir. –