2012-02-14 15 views
34

मान लीजिए मैं दृश्य को जानकारी भेजने के लिए एक आधार नियंत्रक में कुछ तर्क है एक ब्रेडक्रम्ब की तरह कुछ का निर्माण करने के:प्रस्तुत करने से पहले निष्पादित करने के लिए फ़िल्टर करें लेकिन नियंत्रक के बाद?

class ContextAwareController < ApplicationController 

    after_filter :build_breadcrumb 

    def build_breadcumb 
    #... 
    end 
end 

मैं इस build_breadcrumb विधि मुख्य नियंत्रक तर्क के बाद चलाना चाहते हैं, लेकिन से पहले दृश्य प्रस्तुत किया जाता है।

ऊपर कोड बहुत देर हो चुकी चलाता है, लेकिन एक before_filter बहुत जल्दी होगा।

किसी को भी स्पष्ट रूप से बच्चे के नियंत्रकों में कार्यों में से प्रत्येक के अंत में build_breadcumb बुला बिना यह पूरा करने के लिए एक तरह से बता सकते हैं?

धन्यवाद

उत्तर

2

मैं शुरू होता है प्रतिपादन मानना ​​है कि जब प्रस्तुत करना कहा जाता है, और वहाँ कोई डिफ़ॉल्ट जिस तरह से यह स्थगित करने के लिए।

फिल्टर उसी क्रम घोषित रूप से लागू होते: यहाँ एक बात आप कर पाते थे। तो एक दूसरा बाद फ़िल्टर बनाएं जो क्लास चर में संग्रहीत सरणी तर्कों के साथ प्रस्तुत करता है। फिर कहीं भी आप सामान्य रूप से रेंडर कॉल करेंगे, चर सेट करें।

49

मैं एक ही समस्या थी और इस तरह इसे हल:

class ApplicationController < ActionController::Base 
    def render *args 
    add_breadcrumbs 
    super 
    end 
end 
+2

लेकिन यह समाधान प्रत्येक प्रस्तुत करने में धीमा हो जाएगा। – freemanoid

+1

यह केवल धीमा होगा एक विशेष नियंत्रक से बना बना देता है। यह आसान एक अलग नियंत्रक या "उप नियंत्रक" को यह स्थानांतरित करने के लिए पर्याप्त होगा ताकि केवल कार्यों कि ब्रेडक्रंब जरूरत 'render' के इस संस्करण का उपयोग करें। – Jon

+0

हम भी इस कार्यक्षमता जोड़ने के लिए एक नियंत्रक चिंता का उपयोग कर सकते चुनिंदा http://elegantbrew.tumblr.com/post/70990048275/controller-concerns-in-rails-4 – MhdSyrwan

2

वहाँ भी कुछ जवाहरात इस लक्ष्य को हासिल करने के लिए। उनमें से एक rails3_before_render है। यह फिल्टर करने के लिए इसी तरह काम करता है, उदाहरण के लिए:

class PostsController < ApplicationController 
    before_render :ping, :except => [:destroy] 

    def index; end 
    def new; end 
    def show; end 
    def destroy; end                   

    private 
    def ping 
     Rails.logger.info "Ping-Pong actions" 
    end 
end 

(कोड मणि प्रलेखन से नकल कतरना)

+3

यह भी उल्लेख है कि इस फिल्टर केवल आप अगर निष्पादित किया जाता है लायक है _render_ विधि को कॉल करें, इस प्रकार रीडायरेक्ट की संभावना होने पर डेटाबेस में डेटा अपडेट करने के लिए पहले_रेंडर का उपयोग नहीं किया जाना चाहिए। – knarewski

-1

आप नकली एक before_render को इस तरह कर सकते हैं:

class StuffController < ApplicationController 
    before_filter :my_filter, only: [:index, :show] 

    def my_filter 
    @my_filter = true 
    end 
    def _my_filter 
    # Do the actual stuff here 
    end 
    def render(*args) 
    _my_filter if @my_filter 
    super 
    end 
end 

@joshua के लिए धन्यवाद render

2

का उपयोग करने के बारे में टिप के लिए -मुइम यदि हम render ओवरराइड कर रहे हैं, तो हम वास्तव में फ़िल्टर का उपयोग नहीं कर रहे हैं श्रृंखला बिल्कुल, इसलिए @_action_name का उपयोग करके हम कौन सी कार्रवाई कर रहे हैं यह निर्धारित करना आसान हो सकता है।

StuffController < ApplicationController 

    def my_filter 
    # Do the stuff 
    end 

    def render(*args) 
    my_filter if @_action_name == "show" 
    super 
    end 

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

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