10

के लिए सही प्रकार की स्थिति का उपयोग नहीं करने वाली क्वेरी मेरे पास User बेस क्लास से विरासत में एसटीआई उप-वर्गों का एक सेट है। मुझे लगता है कि सबक्लास 'परिभाषा के अंदर कुछ स्थितियों के तहत, उप-वर्गों पर प्रश्न type स्थिति का सही ढंग से उपयोग नहीं करते हैं।ActiveRecord: एसटीआई सबक्लास

class User < ActiveRecord::Base 
    # ... 
end 

class Admin < User 
    Rails.logger.info "#{name}: #{all.to_sql}" 
    # ... 
end 

जब विकास में रेल सांत्वना लोड हो रहा है, यह मैं क्या उम्मीद करेंगे करता है:

Admin: SELECT `users`.* FROM `users` WHERE `users`.`type` IN ('Admin') 

लेकिन जब एप्लिकेशन (स्थानीय होस्ट/पॉव) मार, यह type हालत याद आ रही है और मैं इस मिल :

Admin: SELECT `users`.* FROM `users` 

लेकिन एप्लिकेशन जब जब एक मचान सर्वर के लिए तैनात से:

Admin: SELECT `users`.* FROM `users` WHERE `users`.`type` IN ('Admin') 

यह, निश्चित रूप से, देव ऐप (लेकिन कंसोल से नहीं) में गलत तरीके से निष्पादित किसी भी प्रश्न का कारण बनता है। विशेष रूप से, मैं उन डेटा के आधार पर कुछ उपयोगी विधियों को बनाने के लिए मौजूदा डीबी मानों के एक (छोटे) कैश को प्रीलोड करने का प्रयास कर रहा हूं। प्रकार के दायरे के बिना, कैश स्पष्ट रूप से गलत है!

एक ही स्थान (Admin), हम निम्नलिखित भ्रामक विरोधाभास मिल से:

[11] pry(Admin)> Admin.finder_needs_type_condition? 
=> true 
[12] pry(Admin)> Admin.send(:type_condition).to_sql 
=> "`users`.`type` IN ('Admin')" 
[13] pry(Admin)> Admin.all.to_sql 
=> "SELECT `users`.* FROM `users`" 

इसके अलावा, मैं user.rb फाइल के अंदर एक throwaway उपवर्ग Q < User परिभाषित किया। मैंने की परिभाषा से, और एक दृश्य से, इसकी परिभाषा से Q.all.to_sql को लॉग किया। इसी क्रम में, हम पाते हैं:

From Q: Q: SELECT `users`.* FROM `users` WHERE `users`.`type` IN ('Q') 
From Admin: Q: SELECT `users`.* FROM `users` 
From View: Q: SELECT `users`.* FROM `users` WHERE `users`.`type` IN ('Q') 

कारण बन सकता है क्या, admin.rb में Admin उपवर्ग परिभाषा की पहली पंक्ति में, User में से किसी उपवर्ग अपने type_condition उपयोग करने के लिए विफल?

यह विकास परीक्षण विफल होने का कारण बन रहा है, और इसलिए मेरे ऐप के कुछ परिणाम भी हैं। पृथ्वी पर क्या इस व्यवहार को व्यवहार में ला सकता है? क्या कोई अपनी परिभाषा के दौरान विकास एप पर्यावरण में केवल एसटीआई शर्तों को परिभाषित करने की समस्या के आसपास एक सामान्य तरीका सोच सकता है? उत्पादन और विकास के बीच

उत्तर

4

एक अंतर यह आवेदन विन्यास के अंदर निम्न पंक्ति है:

# config/environments/development.rb 
config.eager_load = false 

बनाम

# config/environments/production.rb 
config.eager_load = true 
अपने उत्पादन वातावरण पर

तो, अपने सभी clases लोड किए गए हैं जब एप्लिकेशन शुरू हो गया। जब eager_load गलत पर सेट किया गया है, तो रेल आपके User कक्षा को स्वत: लोड करने का प्रयास करेंगे जब आप पहली बार Admin कक्षा लोड करते हैं।

यह देखते हुए कि, मुझे लगता है कि आपके पास User नामक एक और वर्ग या मॉड्यूल है।

FYI: ActiveRecord में finder_needs_type_condition? नामक एक विधि है।यह एक वर्ग एसटीआई का उपयोग करता है के लिए सच लौटना चाहिए:

User.finder_needs_type_condition? # should be false 
Admin.finder_needs_type_condition? # should be true 
+0

युक्तियों के लिए धन्यवाद। मुझे उत्सुक लोड अंतर मिलता है, लेकिन यह अभी भी रहस्यमय है कि यह मुद्दा देव कंसोल में मौजूद नहीं है, लेकिन * देव * में मौजूद है (जब मैं लोकलहोस्ट/पाउ का उपयोग करता हूं)। 'Finder_needs_type_condition?' विधि के बारे में जानना अच्छा है: फिर भी, जब मैं ऐप से प्रिये करता हूं तो यह 'सत्य' देता है जबकि मुझे अभी भी 'उपयोगकर्ताओं को चुनें'। * प्रश्न में '' '' '' '। संबंधित रूप से, मुझे निजी विधि 'type_condition' मिला, जो' to_sql' पर कॉल करते समय, '''' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' _ ' तो कुछ स्पष्ट रूप से तोड़ दिया गया है। –

+0

संबंधित, मैं ** पूरी तरह से अलग बेस क्लास के किसी अन्य एसटीआई सबक्लास पर इस व्यवहार को दोहराने में सक्षम नहीं था, इसलिए ऐसा लगता है कि विशेष रूप से 'उपयोगकर्ता' वर्ग के साथ कुछ करना है। प्रगति ... –

+0

एक और अपडेट: मैंने कक्षा की घोषणा के अलावा अपने 'उपयोगकर्ता' बेस क्लास में * सबकुछ * टिप्पणी की है, और यह मुद्दा बनी हुई है। तो मैं नहीं देख सकता कि इस कक्षा के बारे में अब क्या विशेष हो सकता है, या कक्षा परिभाषा समाप्त होने के बाद जो भी समस्या हो रही है, वह जो भी हो रहा है। –

1

वर्तमान में, किसी भी User एक खाली :type कॉलम होगा। क्या यह एक समस्या हो सकती है?

क्या आपने User एक सुपर क्लास बनाने की कोशिश की है? जैसे

class User < ActiveRecord::Base 
end 

class Admin < User; end 
class NormalUser < User; end 
+0

अगर मैं कुछ गलत समझ रहा हूं तो मुझे सही करें, मैंने कभी रूबी/रेल में 'abstract_class' का उपयोग नहीं किया है। दस्तावेज़ों को पढ़ना, मैं देखता हूं कि 'abstract_class' को 'सत्य' पर सेट किया जाना चाहिए यदि मैं नहीं चाहता हूं कि सबक्लास एक ही तालिका नाम का उपयोग करें। लेकिन मैं करता हूं, इसलिए मुझे यकीन नहीं है कि यह मेरे उपयोग के मामले के लिए सही है। जब मैं इसे आज़माता हूं, तो मुझे लगता है कि आप क्या उम्मीद कर सकते हैं: 'ActiveRecord :: स्टेटमेंट इन्वालिड: MySQL 2 :: त्रुटि: तालिका' threeplay_development.admins 'मौजूद नहीं है। किसी भी 'उपयोगकर्ता' के द्वारा आपका मतलब खाली 'प्रकार' कॉलम होगा? 'उपयोगकर्ता' तालिका सही ढंग से आबादी में है, ऐप शुरू होने पर मुझे उस डेटा को लोड करने की आवश्यकता है। –

+0

अप्स, आप 'abstract_class' के साथ सही हैं: वह बकवास था। हालांकि, ** खाली ** 'प्रकार: कॉलम समस्या। जब आप 'user.create ({विशेषताएँ ....})' निर्दिष्ट किए बिना 'टाइप करें 'टाइप करें' यह' nil' मान प्राप्त करता है। 'Admin.create (...) 'के साथ ही स्वचालित रूप से' टाइप = 'व्यवस्थापक' सेट होता है। – andiba

+0

हाँ, प्रतिक्रिया के लिए धन्यवाद। डेटा पहले से मौजूद है और इसमें 'टाइप' कॉलम आबादी है (वर्तमान में 13k कुल 'उपयोगकर्ता', उनमें से 23 'व्यवस्थापक')। यहां मैं सिर्फ 'Admin.all' (या' self.all' 'एडमिन' क्लास 'परिभाषा के अंदर) का उपयोग कर तालिका से पढ़ रहा हूं, और यह ऊपर उल्लिखित विशिष्ट स्थिति के तहत उचित' WHERE' खंड उत्पन्न नहीं कर रहा है। –

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