प्रति कार्रवाई रेल पटरियों?


165

मैं कुछ क्रियाओं के लिए एक अलग लेआउट का उपयोग करता हूं (ज्यादातर नियंत्रकों में नई कार्रवाई के लिए)।

मैं सोच रहा हूं कि लेआउट को निर्दिष्ट करने का सबसे अच्छा तरीका क्या होगा? (मैं एक ही नियंत्रक में 3 या अधिक विभिन्न लेआउट का उपयोग कर रहा हूं)

मुझे इस्तेमाल करना पसंद नहीं है

रेंडर: लेआउट => 'नाम'

मुझे करना पसंद था

लेआउट 'नाम',: केवल => [: नया]

लेकिन मैं इसका उपयोग 2 या अधिक विभिन्न लेआउट को निर्दिष्ट करने के लिए नहीं कर सकता।

उदाहरण के लिए:

जब मैं लेआउट को 2 बार एक ही कंट्रोलर में, अलग-अलग लेआउट नामों और अलग-अलग एकमात्र विकल्पों के साथ कहता हूं, तो पहले वाले को नजरअंदाज कर दिया जाता है - उन कार्यों को मेरे द्वारा निर्दिष्ट लेआउट में प्रदर्शित नहीं किया जाता है।

नोट: मैं रेल 2 का उपयोग कर रहा हूं।


1
रेल मार्गदर्शिकाएँ दस्तावेज: गाइड.ब्रुयोन्रिल्स.ओआर /
केविन

1
अच्छी बात। रेल 2 के लिए दस्तावेज: guide.rubyonrails.org/v2.3.11/…
केविन

2
(इसके अलावा, मैंने भविष्य के पाठकों की मदद करने के लिए गाइड पोस्ट किया। मुझे इसमें कोई संदेह नहीं है कि आपकी समस्या बहुत समय पहले हल हो गई थी ;-)
केविन

जवाबों:


297

आप लेआउट सेट करने के लिए एक विधि का उपयोग कर सकते हैं।

class MyController < ApplicationController
  layout :resolve_layout

  # ...

  private

  def resolve_layout
    case action_name
    when "new", "create"
      "some_layout"
    when "index"
      "other_layout"
    else
      "application"
    end
  end
end

22
धन्यवाद। और अगर कोई एक-लाइनर के साथ सरल चीजें करना चाहता है तो निम्नलिखित संभव है। नियंत्रक के शीर्ष पर पढ़ने और जगह करने में आसान है। ---layout Proc.new{ ['index', 'new', 'create'].include?(action_name) ? 'some_layout' : 'other_layout' }
होली

1
यदि विभिन्न लेआउट कई अलग-अलग सीएसएस और js फ़ाइलों को क्रमशः उपयोग कर रहे हैं, तो क्या इससे एप्लिकेशन के प्रदर्शन पर बड़ा प्रभाव पड़ेगा?
नोज़

15
-1: बहुत जटिल। नीचे टिप्पणी ( stackoverflow.com/a/21203783/285154 ) सबसे अच्छा विकल्प है।

धन्यवाद! यह अभी भी रेल 4.2 में एक समस्या है, शायद तभी जब आप कई स्तरों में विरासत नियंत्रक का उपयोग कर रहे हों। मैंने पहले विधि का उपयोग किया है, लेकिन परीक्षण के बारे में नहीं सोच रहा था कि जब मुझे अब समस्या थी, तो फिर से धन्यवाद।
244

@dimitko नहीं यह नहीं है, मैंने पहले ही प्रश्न में उस समाधान का उल्लेख किया है। यह काम नहीं करता है यदि आप 3 या अधिक विभिन्न लेआउट का उपयोग करना चाहते हैं (जैसा कि वास्तव में मेरा मामला है)।
श्रीब्रांडो

201

यदि आप केवल दो लेआउट के बीच चयन कर रहे हैं, तो आप उपयोग कर सकते हैं :only:

class ProductsController < ApplicationController
   layout "admin", only: [:new, :edit]
end

या

class ProductsController < ApplicationController
   layout "application", only: [:index]
end

2
ठीक है, इस के साथ समस्या यह है कि आप वर्तमान रूप से लेआउट को निर्धारित करने के लिए वर्तमान_सियर जैसी वस्तुओं तक नहीं पहुंच सकते हैं
एंड्रयू के

@AndrewK डायनामिक रूप से एक लेआउट का चयन करना पूछे गए प्रश्न का हिस्सा नहीं लगता है।
निक

11
यदि आप में से कोई भी प्रश्न पढ़ता है तो आपको पता होगा कि यह सही उत्तर नहीं है, जैसा कि मैंने पहले ही इस प्रश्न में हल बता दिया है और यह भी कि यह मेरे मामले में काम नहीं करता है (3 या अधिक लेआउट)।
mrbrdo

2
जैसे मृब्रदो ने कहा, यह उत्तर नहीं है। उनका प्रश्न विशेष रूप से इंगित करता है (I am using 3 or more different layouts in the same controller)। यह उत्तर एक लेआउट और कोई लेआउट की अनुमति देता है, न कि विभिन्न लेआउट।
माइकल

49

आप answer_to का उपयोग करके किसी व्यक्तिगत कार्रवाई के लिए लेआउट निर्दिष्ट कर सकते हैं :

  def foo
    @model = Bar.first
    respond_to do |format|
      format.html {render :layout => 'application'}
    end
  end

मेरे लिए यह अधिक लचीला जवाब है। layout "[...]" to the controller class only allows one statement effectively. If you have more than two layouts to deal with (say, admin, generic_app, tailored_app), you will experience रेंडर और / या रीडायरेक्ट को लागू करके चीजों को बाहर निकालना इस कार्रवाई की त्रुटियों में कई बार कहा गया; और आपके पास इस सुझाव का उपयोग करने के अलावा कोई विकल्प नहीं है।
जेरोम

1
यह उत्तर सबसे अच्छा है, इसके सरल और साफ-सुथरे तरीकों का उपयोग करने के विरोध में या यदि कथन अंदर है।
केव

यह भी एरब फ़ाइल और लेआउट दोनों को निर्दिष्ट कर सकता है: format.html { render 'custom_index', layout: 'application' } उसी तरह से।
thatway_3

12

आप रेंडर का उपयोग करके कार्रवाई के लिए लेआउट भी निर्दिष्ट कर सकते हैं:

def foo
  render layout: "application"
end


7

नियंत्रक के तहत लेआउट को निर्दिष्ट करने के विभिन्न तरीके:

  1. निम्नलिखित कोड में, एप्लिकेशन_1 लेआउट को इंडेक्स के तहत कहा जाता है और उपयोगकर्ता नियंत्रक और एप्लिकेशन लेआउट (डिफ़ॉल्ट लेआउट) की कार्रवाई को अन्य कार्यों के लिए कहा जाता है।

    class UsersController < ApplicationController
      layout "application_1", only: [:index, :show]
    end
  2. निम्नलिखित कोड में, उपयोक्ता नियंत्रक की सभी क्रियाओं के लिए application_1 लेआउट को कहा जाता है।

    class UsersController < ApplicationController
       layout "application_1"
    end
  3. निम्नलिखित कोड में, एप्लिकेशन_1 लेआउट को केवल उपयोगकर्ता नियंत्रकों की परीक्षण कार्रवाई के लिए और अन्य सभी कार्रवाई एप्लिकेशन लेआउट (डिफ़ॉल्ट) के लिए कहा जाता है।

        class UsersController < ApplicationController
          def test
            render layout: "application_1"
          end
        end

5

परिशुद्धता:

वास्तव में नहीं बल्कि कार्यशील DRY तरीका है जो आप ऊपर देख रहे हैं, लेकिन एक सटीकता के साथ: काम करने के लिए आपके चर के बाद लेआउट की आवश्यकता है ("@some")। जैसा :

def your_action
   @some = foo
   render layout: "your_layout"
end

और नहीं :

def your_action
   render layout: "your_layout"
   @some = foo
   @foo = some
end

यदि आप पहले से काम करते हैं ... तो यह भी काम नहीं करेगा।

आशा करता हूँ की ये काम करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.