2009-04-30 15 views
8

मैं क्वेरी पैरामीटर और डेटाबेस में डेटा के संयोजन के आधार पर एक नियंत्रक कार्रवाई से दूसरे सशर्त रूप से प्रेषण करने में सक्षम होना चाहता हूं।एक HTTP नियंत्रक के बिना किसी अन्य नियंत्रक कार्रवाई से एक नियंत्रक कार्रवाई चलाने का सही तरीका क्या है?

क्या मैं अभी की तरह कुछ है:

class OldController < ApplicationController 
    def old_controller_action 
    if should_use_new_controller 
     new_params = params.dup 
     new_params[:controller] = "new_controller_action" 
     redirect_to new_params 
     return 
    end 
    # rest of old and busted 
    end 
end 

class NewController < ApplicationController 
    def new_controller_action 
    # new hotness 
    end 
end 

यह सिर्फ ठीक काम करता है, लेकिन यह एक HTTP रीडायरेक्ट, जो धीमी है जारी करता है। मैं वही काम करने में सक्षम होना चाहता हूं, लेकिन उसी HTTP अनुरोध के भीतर।

क्या ऐसा करने का कोई साफ तरीका है?

संपादित करें: बकाया किसी ऐसे व्यक्ति के पास जाएगा जो मुझे ऐसा करने का एक साफ तरीका दिखा सकता है जो नियंत्रकों और उनके कार्यों को अपेक्षाकृत छूटे हुए (रीडायरेक्ट कोड के अलावा) छोड़ देता है।

उत्तर

13

क्रियाओं में कोड कॉल करने के बजाय, कोड को lib/या कुछ में निकालें, और दोनों नियंत्रकों से कोड को कॉल करें।

@my_other_controller = MyOtherController.new 

फिर उस पर तरीकों फोन:

# lib/foo.rb 
module Foo 
    def self.bar 
    # ... 
    end 
end 

# posts_controller 
def index 
    Foo.bar 
end 

# things_controller 
def index 
    Foo.bar 
end 
+0

हाँ, मैंने इसके बारे में भी सोचा था, हालांकि यह एक कोड संगठन परिप्रेक्ष्य से एक बहुत ही रोमांचक विकल्प नहीं है। –

+1

यह वास्तव में ठीक है क्योंकि यह दो स्थानों से बुलाया जा सकता है जो आसानी से टेस्टेबल –

7

नियंत्रक वर्ग का एक उदाहरण बनाने

@my_other_controller.some_method(params[:id]) 

मैं मॉड्यूल विचार पसंद करते हैं, लेकिन इस चाल करना चाहिए।

+0

है, यह बहुत अच्छा काम नहीं करेगा। नियंत्रक के इस नए उदाहरण के अंदर 'रेंडर' विधि को कॉल करना मुश्किल है। यदि आप मूल नियंत्रक में रेंडर कॉल करते हैं तो आप कॉल कंट्रोलर में सेट किए गए सभी चर खो देंगे। – holli

1

मुझे लगता है आप विकल्प 3 चाहते हैं, लेकिन कुछ पहले

विकल्प 1 विकल्प के माध्यम से जाने की सुविधा देता है - एक सहायक है कि आपके विचार में सही लिंक सम्मिलित करता है में नियंत्रक चयन तर्क पुश। Benifits - नियंत्रक स्वच्छ रहते हैं, विपक्ष - यदि सबमिट मूल्यों के आधार पर निर्णय तर्क इस दृष्टिकोण काम नहीं करेगा। यदि बाहरी वेबसाइटों द्वारा यूआरएल बुलाया जा रहा है तो यह काम नहीं करेगा।

विकल्प 2 - तर्क को अपने मॉडल में वापस दबाएं। प्रो - नियंत्रक को साफ रखता है। विपक्ष - यदि आपके पास बहुत से सैसन, पैराम या रेंडर/रीडायरेक्ट_ इंटरैक्शन के लिए बहुत अच्छा काम नहीं है।

विकल्प 3 - एक ही नियंत्रक के भीतर रहें। मुझे संदेह है कि आप कुछ मौजूदा कार्यक्षमताओं को कुछ नई कार्यक्षमता के साथ बदलने की कोशिश कर रहे हैं, लेकिन केवल कुछ मामलों में। प्रो - सरल और आपको जो भी चाहिए उसे एक्सेस करें। विपक्ष - केवल तभी काम करता है जब यह एक ही नियंत्रक का उपयोग करने के लिए समझ में आता है यानी आप उपयोगकर्ता, स्थान या कंपनी जैसी ही इकाई के साथ काम कर रहे हैं।

विकल्प 3. मेरी लिंक नियंत्रक अन्य उपयोगकर्ताओं से व्यवस्थापकों के लिए पूरी तरह से विभिन्न behavour है ...

class LinksController < ApplicationController 
    #... 

    def new 
    #Check params and db values to make a choice here 
    admin? ? new_admin : new_user 
    end 

    #... 

private 

    def new_admin 
    #All of the good stuff - can use params, flash, etc 
    render :action => 'new_admin'  
    end 

    def new_user 
    #All of the good stuff - can use params, flash, etc 
    render :action => 'new_user' 
    end 

end 
0

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

http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model http://www.robbyonrails.com/articles/2007/06/19/put-your-controllers-on-a-diet-already http://andrzejonsoftware.blogspot.com/2008/07/mvc-how-to-write-controllers.html

समस्या है, तो: अपने डिजाइन पर एक अच्छा नज़र डालें और - - मैं माफी चाहता मैं MVC के साथ अपने अनुभव के स्तर का पता नहीं है हूँ पतली नियंत्रक तकनीक के बारे में पढ़ें कि आपको रेंडर करने के लिए अन्य नियंत्रक की आवश्यकता है, तो शायद मार्ग को वहां से इंगित करने के लिए इंगित किया जाना चाहिए था, और फिर भी पतला नियंत्रक तकनीक दिन को बचा लेनी चाहिए। यदि एक मॉड्यूल में नियंत्रकों के बीच आम कोड निकालने के लिए काम नहीं करता है

class NewController < OldController 
    def new_controller_action 
    # new hotness 
    end 
end 
-1

ऐसा करें। मैंने कोड नहीं देखा है जो ActiveRecord का उपयोग मिडलवेयर के भीतर करता है लेकिन मुझे किसी भी कारण से पता नहीं है कि यह संभव नहीं होना चाहिए क्योंकि लोगों ने Redis और इसी तरह का उपयोग किया है।

अन्यथा मुझे लगता है कि अपने ही एकमात्र विकल्प (अपरीक्षित, छद्म उदाहरण) की तरह कुछ के साथ अनुरोध के संसाधन को पुनः आरंभ करने होगा:

env['REQUEST_URI'] = new_controller_uri_with_your_params 
call(env) 

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

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

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

0

class OldController < ApplicationController 
    def old_controller_action 
    if should_use_new_controller 
     new_controller_action 
    end 
    # rest of old and busted 
    end 
end 

और नए नियंत्रक, मैं रैक मिडलवेयर का प्रयोग करेंगे:

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