6

परिवर्तित नहीं करता है मुझे टाइमज़ोन और पोस्टग्रेस्क्ल डीबी (रेल 3.0.4, पोस्टग्रेएसक्यूएल 9.0) के साथ समस्या है। मैं एक कस्टम स्कोप का उपयोग कर रहा हूं, जिसमें मैं कुछ शर्तों को जोड़ता हूं, शामिल हूं आदि।रेल टाइमज़ोन (पोस्टग्रेएसक्यूएल)

समस्या यह है कि रेल समय को मेरे स्थानीय टाइमज़ोन में परिवर्तित नहीं करते हैं।

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

और चुनें बयान में, मैं starting_at TRUNC हैं:

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 गुंजाइश इस रिटर्न: यहाँ दायरे से कोड है दिन के लिए क्षेत्र।

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

दुर्भाग्य से यह समय क्षेत्र शामिल नहीं है:

मैं दिनांक फ़ील्ड के लिए निम्न उत्पादन हो रही है। जब मैं "सामान्य" रेल कार्यों के माध्यम से अपने मॉडल तक पहुंचने का प्रयास करता हूं, तो यह काम करता है:

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

मैं क्या गलत कर रहा हूं? उम्मीद है कि कोई मदद कर सकता है!

THX, टक्स

+0

डेटाबेस के अंदर 'activities.starting_at' किस प्रकार का है? और क्या होता है यदि आप 'psql' के भीतर से 'गतिविधियों से start_at का चयन करें'? –

+0

'activities.starting_at' एक टाइमज़ोन के बिना 'टाइमस्टैम्प' है (यूटीसी में संग्रहीत)। 'गतिविधियों' रिटर्न से start_at का चयन करें '2011-04-15 04: 47: 34', बिना टाइमज़ोन के। लेकिन क्या रेलों को फ्लाई पर विशिष्ट टाइमज़ोन में समय नहीं बदलना चाहिए? मेरे प्रश्न से मेरे उदाहरण के साथ 'Activity.first.starting_at -> 2011-04-15 06:47:55 + 0200' यह काम करता है। – 23tux

+0

मुझे एक और दिलचस्प बात मिली: जब मैं परिणामों पर पुन: प्रयास करता हूं, और अपने दिनांक क्षेत्र की कक्षा को डंप करता हूं, तो मुझे 'स्ट्रिंग' मिलता है। लेकिन यह 'ActiveSupport :: TimeWithZone' होना चाहिए। मैंने postgresql के प्रलेखन को पढ़ा है, और 'date_trunc ('day', activities.starting_at) 'को' टाइमस्टैंप 'वापस करना चाहिए। रेल इसे क्यों परिवर्तित नहीं करते हैं? – 23tux

उत्तर

5

आपका डेटाबेस यूटीसी में अपना टाइम स्टांप भंडारण किया जाता है (जैसा कि होना चाहिए)। ActiveRecord टाइमज़ोन समायोजन कर रहा है जब यह जानता है कि इसमें टाइमस्टैम्प है; इसलिए, जब आप कहते हैं इस:

puts Activity.first.starting_at 

एआर जानता है कि starting_at एक टाइमस्टैम्प है, इसलिए यह एक उदाहरण के रूप में ActiveSupport::TimeWithZone टाइमस्टैम्प को दर्शाता है और उस वर्ग समय क्षेत्र समायोजन लागू होता है। लेकिन, जब आप कहते हैं इस:

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

एआर यह पता लगाने की है कि date_trunc एक टाइमस्टैम्प वापस आ जाएगी एसक्यूएल पार्स करने के लिए नहीं जा रहा है, एआर भी पता नहीं है क्या date_trunc साधन। एआर डेटाबेस से बाहर आने वाली स्ट्रिंग को देखेगा और यह बिना किसी व्याख्या के आपको सौंप देगा। आप उस स्ट्रिंग को ActiveSupport::TimeWithZone (या अपनी पसंदीदा टाइम हैंडलिंग क्लास) पर फ़ीड करने के लिए स्वतंत्र हैं: एआर चीजों को बताने में कुछ भी गलत नहीं है जो यह स्वयं नहीं जानता और नहीं जानता है।

रेल चालाक है लेकिन यह जादू नहीं है।

+0

thx। यही वह था कि मैं कक्षा को डंप करके पता लगाता हूं। आप स्ट्रिंग को 'ActiveSupport :: TimeWithZone'' पर कैसे फ़ीड करेंगे? परिणामों के माध्यम से Iterate और स्ट्रिंग कन्वर्ट? – 23tux

+0

आप वैसे भी परिणामों के माध्यम से फिर से प्रयास करेंगे ताकि आप टाइमविथज़ोन सामान को वहां फेंक सकें। मैं एआर 3 स्कोप गुरु नहीं हूं, हालांकि एक बेहतर तरीका हो सकता है। –

संबंधित मुद्दे