15

जब मेरा रेल ऐप शुरू होता है तो मैं कक्षा विशेषता सेट करना चाहता हूं। इसके लिए कुछ मार्गों की जांच की आवश्यकता है, इसलिए मेरे कस्टम कोड चलाने से पहले मार्गों को लोड करने की आवश्यकता है। मैं मुसीबत में हुक करने के लिए एक विश्वसनीय जगह खोजने हो रहा है* रेलवे प्रारंभकर्ता जो * * मार्गों के बाद * लोड हो जाता है?

यह "परीक्षण" वातावरण में पूरी तरह से काम करता है:।

config.after_initialize do 
    Rails.logger.info "#{Rails.application.routes.routes.map(&:path)}" 
end 

लेकिन यह "विकास" के माहौल में काम नहीं करता है (मार्गों खाली हैं)

अभी के लिए मैं config.to_prepare जो मैं समझता हूँ कि हर अनुरोध से पहले होता है में एक ही कोड चलाकर विकास मोड में काम कर बातें है लगता है। दुर्भाग्य से to_prepare का उपयोग अकेले परीक्षण मोड में काम नहीं कर रहा है, इसलिए नकल।

मुझे उत्सुकता है कि परीक्षण मोड में बाद में शुरू होने से पहले रूट क्यों लोड किए जाते हैं, लेकिन विकास मोड में नहीं। और वास्तव में, इसके लिए सबसे अच्छा हुक क्या है? क्या कोई एकल हुक है जो सभी वातावरणों के लिए काम करेगा?

* मार्गों को फिर से लोड की संपादित करें *

म्यू के सुझाव महान था। इसने मुझे सभी परिवेशों में बाद में आरंभ करने के भीतर मार्गों तक लगातार पहुंच प्रदान की। अपने प्रयोग के मामले के लिए, हालांकि, मुझे लगता है कि मैं अभी भी के बाद से मैं एक मॉडल पर एक वर्ग विशेषता सेट कर रहा हूं, साथ ही to_prepare से कोड को चलाने के लिए की जरूरत है और मॉडलों प्रत्येक अनुरोध से पहले पुनः लोड कर रहे हैं।

तो यहां मैं क्या कर रहा हूं।

[:after_initialize, :to_prepare].each do |hook| 
    config.send(hook) do 
    User.invalid_usernames += Rails.application.routes.routes.map(&:path).join("\n").scan(/\s\/(\w+)/).flatten.compact.uniq 
    end 
end 

यह मेरे लिए थोड़ा गन्दा लगता है। मुझे लगता है कि मैं नहीं बल्कि तरह कुछ करना चाहते हैं:

config.after_initialize do 
    User.exclude_routes_from_usernames! 
end 

config.to_prepare do 
    User.exclude_routes_from_usernames! 
end 

लेकिन मुझे यकीन है कि अगर User सही जगह Rails.application.routes की जांच हो रहा है नहीं कर रहा हूँ। मुझे लगता है कि मैं lib के साथ कोड के साथ एक ही काम कर सकता/लेकिन मुझे यकीन नहीं है कि यह सही है या नहीं।

एक अन्य विकल्प सिर्फ to_prepare पर म्यू के सुझाव लागू करने के लिए है। यही कारण है कि काम करता है लेकिन वहाँ मेरे देव वातावरण में हर अनुरोध पर मार्गों को फिर से लोड एक ध्यान देने योग्य देरी हो रहा है, तो मुझे यकीन है कि अगर यह एक अच्छा कॉल है नहीं कर रहा हूँ, हालांकि यह सूखी है, कम से कम।

config.to_prepare do 
    Rails.application.reload_routes! 
    User.invalid_usernames += Rails.application.routes.routes.map(&:path).join("\n").scan(/\s\/(\w+)/).flatten.compact.uniq 
end 

उत्तर

22

आप इस के साथ Rails.application.routes को देख से पहले लोड करने के लिए मार्गों के लिए मजबूर कर सकते हैं:

Rails.application.reload_routes! 

तो अपने config/application.rb में इस प्रयास करें:

config.after_initialize do 
    Rails.application.reload_routes! 
    Rails.logger.info "#{Rails.application.routes.routes.map(&:path)}" 
end 

मैं समान कार्य कर लेते हैं कि मार्गों की जांच करने के लिए आवश्यक है (/:slug मार्गों के साथ संघर्ष के लिए) और मैंने reload_routes! डालने औरमें चेकिंग समाप्त कर दीजैसे आप कर रहे हैं।

+0

अच्छा विचार है! बाहर निकलता है हम वास्तव में एक ही चीज़ के लिए इसका उपयोग कर रहे हैं (मैं 'user_valid_usernames' नामक 'class_attribute' को अपडेट कर रहा हूं जिसे 'validates_exclusion_of' के साथ बहिष्करण सूची के रूप में उपयोग किया जाता है)। मुझे लगता है कि मुझे अभी भी विकास मोड के लिए to_prepare की आवश्यकता है। इसके बिना, यह पहले अनुरोध पर ठीक काम करता है (अब जब मैं आपके सुझाव का उपयोग कर रहा हूं), लेकिन उसके बाद मुझे लगता है कि मेरा 'User.invalid_usernames = Set.new' इसे क्लोबबर कर रहा है। ऐसा लगता है कि आप केवल बाद में उपयोग कर रहे हैं, हालांकि, मैं सोच रहा हूं कि क्या आपके पास कुछ चतुर तरीका है? – poochenza

+0

इस उत्तर में बहुत मदद मिली, इसलिए मैं इसे स्वीकार कर रहा हूं हालांकि मैंने इसका उपयोग नहीं किया है (अगर आपको लगता है कि मुझे चाहिए तो आलोचना के लिए खुला!) मेरा पूरा समाधान है, यदि आपके पास समय है तो आपकी प्रतिक्रिया से प्यार होगा: http: //stackoverflow.com/a/8713207/1126857 – poochenza

+0

@poochenza: मैंने यह सुनिश्चित करने के लिए 'after_initialize' का उपयोग किया है कि रिलीज के बीच कोई नया संघर्ष दिखाई नहीं दे रहा है: यदि आप 'पेनकेक्स' मार्ग जोड़ते हैं और दो सप्ताह बाद प्रकाशित करते हैं, तो आप जानना चाहते हैं कि क्या किसी ने औसत समय में उत्पादन प्रणाली पर "पेनकेक्स" उपयोगकर्ता बनाया। फिर मैं मार्गों के खिलाफ नए उपयोगकर्ता नामों की तुलना करता हूं क्योंकि उपयोगकर्ता नाम बनाए या अपडेट किए जाते हैं। –

2

आप के बाद मार्गों भरी हुई है एक प्रारंभकर्ता में कोड को चलाने के लिए कोशिश कर रहे हैं, तो आप after: विकल्प का उपयोग करके कर सकते हैं:

initializer "name_of_initializer", after: :add_routing_paths do |app| 
    # do custom logic here 
end 

आप प्रारंभ घटनाओं यहाँ पा सकते हैं: http://guides.rubyonrails.org/configuring.html#initialization-events

+0

रेलवे में यह प्रारंभकर्ता कभी मेरे लिए निष्पादित नहीं होगा 4.1.14.1 – nolith

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