2011-08-02 7 views
15

से मार्ग लोड करने के मार्गों को नियंत्रित करना तो रेल 3 इंजन में अपने मॉडल/नियंत्रक/विचार और पाठ्यक्रम मार्गों के साथ आते हैं। अब सवाल यह है कि आप कैसे सुनिश्चित करते हैं कि इंजन मार्ग (या बाद में) आवेदन मार्गों और अन्य सभी इंजनों से पहले लोड किए जाएंगे?इंजन

यहाँ मेरी रेल एप्लिकेशन मार्गों में से एक उदाहरण है:

match '*(path)', :to => 'foo_controller#bar_action' 

और मेरे इंजन:

match '/news', :to => 'bar_controller#foo_action' 
डिफ़ॉल्ट इंजन मार्गों से

तो आवेदन लोगों के बाद लोड किया जाएगा। इसका मतलब है कि मेरे ऐप में उस पकड़-पूरे मार्ग के कारण इंजन मार्ग पहुंच योग्य नहीं हैं। इंजन मार्गों को पहले लोड किया जा सकता है (या आखिरी)?

+0

आप http://edgeguides.rubyonrails.org/configuring.html को देख करने की कोशिश की है? मैं बहुत यकीन है कि आप कर सकते हैं क्या आप हुक और initializers का उपयोग कर चाहते –

+0

है कर रहा हूँ कि अपना डुप्लिकेट नहीं http://stackoverflow.com/questions/6310832/how-to-override-rails-app-routes-from-an- इंजन? –

+0

बीटीडब्लू, मेरा मानना ​​है कि इंजन मार्ग हमेशा ऐप मार्गों के बाद लोड होते हैं। –

उत्तर

28

आप जो करने की कोशिश कर रहे हैं वह बहुत मुश्किल है। जैसा कि बताया गया है कि ऐप मार्गों के बाद इंजन मार्ग लोड किए गए हैं और इस व्यवहार को ओवरराइड करना समस्याग्रस्त हो सकता है। मैं कई चीजों के बारे में सोच सकता हूं जिन्हें आप कोशिश कर सकते हैं।

उपयोग एक प्रारंभकर्ता बाद रूटिंग पथ प्रारंभकर्ता

engine.rb में एक प्रारंभकर्ता रेल स्रोत के अंदर, एक तरह से पूरा करने के लिए कार्यक्षमता है कि यह साथ सौदों में हुक करने की कोशिश करने के लिए है के बाद आप क्या कर रहे हैं नहीं है।

initializer :add_routing_paths do |app| 
    paths.config.routes.to_a.each do |route| 
    app.routes_reloader.paths.unshift(route) if File.exists?(route) 
    end 
end 

मूलतः, यह सभी मार्गों फ़ाइलों को रेल के बारे में जानता पथ लेने के लिए और कोशिश करते हैं और (मार्गों reloader में शामिल करें बात reloades कि आपके मार्गों के लिए पूर्ण रूप से अपने दायर करनी चाहिए: प्रारंभकर्ता डिफ़ॉल्ट रूप से इस तरह दिखता है अगर आप बदल गए हैं)। आप इसके बाद किसी अन्य प्रारंभकर्ता को निष्पादित करने के लिए परिभाषित कर सकते हैं, फिर आप रूट रीलोडर में संग्रहीत पथों का निरीक्षण करेंगे, अपने इंजन से संबंधित पथ खींचें, इसे पथ सरणी से हटा दें और इसे वापस डालें, लेकिन अंत में पथ सरणी के। तो, अपने config/application.rb में:

class Application < Rails::Application 
    initializer :munge_routing_paths, :after => :add_routing_paths do |app| 
    engine_routes_path = app.routes_reloader.paths.select{|path| path =~ /<regex that matches path to my engine>/}.first 
    app.routes_reloader.paths.delete(engine_routes_path) 
    app.routes_reloader.paths << engine_routes_path 
    end 
end 

यह या काम नहीं हो सकता है, किसी भी तरह से मैं सच में इसकी सलाह नहीं देते, यह विशेष रूप से सुंदर (अर्थात बदसूरत रेल की हिम्मत के साथ खेल हैक) है।

उपयोग रेल 3.1

यह एक विकल्प नहीं हो सकता है, लेकिन अगर यह है, मैं शायद इस एक के साथ जाना चाहते हैं। रेल 3.1 में आपके पास 2 अलग-अलग प्रकार के इंजन हो सकते हैं, पूर्ण और आरोही (यहां an SO question talking about some of the differences है)। लेकिन संक्षेप में आप अपने इंजन को एक माउंटेबल इंजन के रूप में बदल देंगे, एक आरोही इंजन में मार्गों का नाम रखा गया है और आप स्पष्ट रूप से उन्हें अपने मुख्य ऐप की रूट फ़ाइल में शामिल कर सकते हैं।:

Rails.application.routes.draw do 
    mount MyEngine::Engine => "/news" 
end 

भी कर सकते हैं गुंजाइश अपने स्थापित इंजन मार्गों और अन्य फैंसी routy बातें (अधिक जानकारी here) के सभी प्रकार से करते हैं। लंबी कहानी छोटी, यदि आप 3.1 पर जा सकते हैं तो यह उपयोग करने का दृष्टिकोण है।

गतिशील रूप से सम्मिलित आपका इंजन से मार्गों आपका मुख्य अनुप्रयोग

सबसे प्रसिद्ध रेल इंजन में से एक में इस समय चारों ओर वसीयत है। अब, वसीयत एक इंजन जो संभवत: आपके अनुप्रयोग के लिए काफी मार्गों का जोड़ देगा है, लेकिन अगर आप वसीयत स्रोत पर गौर करेंगे, तो आप देखेंगे कि यह वास्तव में सब पर एक config/routes.rb फ़ाइल नहीं है कि! इसका कारण यह है वसीयत गतिशील आपका मुख्य एप्लिकेशन की routes.rb फाइल करने के लिए अपने मार्ग अच्छाई जोड़ता है।

जब आप मॉडल जनरेटर है कि वसीयत के साथ आता है चलाने के लिए, चीजों जनरेटर क्या करेंगे में से एक अपने routes.rb फ़ाइल के शीर्ष पर एक लाइन जैसे devise_for :model जोड़ने के लिए, सही Rails.application.routes.draw do लाइन के बाद है। तो अपने route.rb इस के समान लगता है आप एक उपयोगकर्ता मॉडल बनाने के लिए एक जनरेटर पर अमल के बाद:

Rails.application.routes.draw do 
    devise_for :users 
    ... 
end 

अब, devise_for एक जादुई विधि (lib/devise/rails/routes.rb में) युक्ति के हिस्से के रूप में आता है, लेकिन संक्षेप में कहीं भी होगी नियमित मार्गों का एक गुच्छा बनाएं जो हम सभी आपके द्वारा जेनरेट किए गए मॉडल के आधार पर जानते हैं।

बात हम जानते हैं की जरूरत है, कैसे डालने routes.rb फ़ाइल क्षुधा में इस लाइन वसीयत, तो हम अपने इंजन में एक जनरेटर है कि मुख्य क्षुधा routes.rb फ़ाइल के शीर्ष पर हमारे मार्गों में से किसी से जोड़ दिया जाएगा लिख ​​सकते हैं। इसके लिए हम lib/generators/devise/devise_generator.rb देखें। add_devise_routes विधि में अंतिम पंक्ति route devise_route है। Route एक थोर कार्रवाई जो स्ट्रिंग मुख्य एप्लिकेशन की routes.rb फाइल में इसे करने के लिए पारित कर दिया सम्मिलित करता है। इसलिए हम अपने खुद का एक जनरेटर लिख सकते हैं और कुछ इसी तरह, उदा कर .:

class MyCrazyGenerator < Rails::Generators::NamedBase 
    ... 
    def add_my_crazy_routes 
    my_route = "match '/news', :to => 'bar_controller#foo_action'" 
    route my_route 
    end 
end 
बेशक आप सुनिश्चित करें कि सभी जनरेटर बुनियादी सुविधाओं जगह में है बनाने के लिए की आवश्यकता होगी के

लेकिन है कि यह का सार है। डेविस कुछ बहुत ही स्मार्ट रेल दोस्तों द्वारा लिखा जाता है और बहुत से लोगों द्वारा उपयोग किया जाता है, जो वे करते हैं उन्हें अनुकरण करने की संभावना है कि जाने का एक अच्छा अच्छा तरीका है। 3 चीजों में से मैंने सुझाव दिया है कि मैं आपकी समस्या को संभालने का तरीका होगा (यह देखते हुए कि रेल 3.1 पर जाने के लिए शायद एक विकल्प नहीं है)।

+0

यह बहुत अच्छा है। इसका उत्तर देने के आपके लिए धन्यवाद। – Grocery

+0

मैंने अपने सपनों पर छोड़ दिया और वास्तविक रूटिंग कोड को पकड़ने वाले बंदर के बजाय तैयार दृष्टिकोण का उपयोग किया, अंत में यह अधिक लचीला है, खासकर जब आप कस्टम स्कॉप्स में चीजें लपेट रहे हैं। –

0

मैं एक विशेषज्ञ नहीं हूं, लेकिन जब मैं अपने रूटिंग समाधान में आया तो मैं कल sferik/rails_admin के साथ खेल रहा था। उनके rails_admin:install रेक कार्य के साथ, वे फ़ाइल की शुरुआत में mount RailsAdmin::Engine => '/admin', :as => 'rails_admin' जोड़ कर अपनी config/routes.rb फ़ाइल को सीधे संशोधित करते हैं ताकि वे सुनिश्चित हों कि उनके मार्गों की हमेशा उच्च प्राथमिकता हो। यही कारण है कि mount विधि अपने स्वयं के routes.rb को दर्शाता है:

RailsAdmin::Engine.routes.draw do 
    # Prefix route urls with "admin" and route names with "rails_admin_" 
    scope "history", :as => "history" do 
    controller "history" do 
     [...] 
    end 
    end 
end 

इस अपने समाधान हो सकता है?

2

अभी भी यही समस्या है। एक अन्य विशेष रूप से सुरुचिपूर्ण लेकिन सुरक्षित नहीं समाधान मैं के साथ अपने मणि फ़ाइल के अंत में एक और इंजन मणि जोड़ रहा है, बस पकड़ सभी मार्ग, और कुछ नहीं युक्त आया।

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

+1

हाँ। जब तक यह रणनीति काम नहीं करता है तब तक यह मूल रूप से रत्नों को घूमता है।रत्नों के लिए यह एक तरीका प्रदान करना बेहद बेहतर है कि आप स्पष्ट रूप से अपने मार्गों के भीतर कॉल करते हैं। आरबी। इस तरह आप नियंत्रित कर सकते हैं कि आप कहां उन मार्गों को चाहते हैं (यदि बिल्कुल)। – Grocery

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