2012-02-29 14 views
183

मैं Getting Started with Rails मार्गदर्शिका के माध्यम से जा रहा हूं और अनुभाग 6.7 के साथ भ्रमित हो गया हूं।रेल: प्रतिक्रिया_to ब्लॉक कैसे काम करता है?

def index 
    @posts = Post.all 

    respond_to do |format| 
    format.html # index.html.erb 
    format.json { render :json => @posts } 
    end 
end 

मैं समझता हूँ कि कैसे respond_to ब्लॉक वास्तव में काम करता है करना चाहते हैं: एक पाड़ जेनरेट करने के बाद मैं अपने नियंत्रक में निम्न स्वत: उत्पन्न ब्लॉक पाते हैं। किस प्रकार का चर प्रारूप है? प्रारूप ऑब्जेक्ट के .html और .json विधियां हैं? ActionController::MimeResponds::ClassMethods::respond_to के लिए प्रश्न का उत्तर नहीं देता है।

+0

यह अच्छा होगा अगर मैं ActionController :: MimeResponds :: ClassMethods :: respond_to के लिए प्रलेखन से लिंक कर सकता हूं लेकिन api.rubyonrails.org सीधे हाइपरलिंक्स की तरह प्रतीत नहीं होता है ... – Cole

+0

answer_to कॉल का अंत लेता है (उदाहरण के लिए blah.html, blah.json, आदि) और निर्दिष्ट दृश्य से मेल खाता है। आवेदन के आधार पर अन्य प्रतिक्रियाएं एक्सएमएल, सीएसवी और कई अन्य हो सकती हैं। – ScottJShea

+4

यह "निर्दिष्ट दृश्य से कैसे मेल खाता है?" – Cole

उत्तर

95

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

respond_to एक रेल सहायक सहायक विधि है जो नियंत्रक वर्ग (या बल्कि, इसकी सुपर क्लास) से जुड़ी है। यह उस प्रतिक्रिया का संदर्भ दे रहा है जो दृश्य को भेजा जाएगा (जो ब्राउज़र पर जा रहा है)।

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

यदि आप अपनी स्थानीय मशीन पर हैं और आपके पास पोस्ट पोस्ट मचान है, तो आप http://localhost:3000/posts पर जा सकते हैं और आप अपनी सभी पोस्ट HTML प्रारूप में देखेंगे। लेकिन, यदि आप इसमें टाइप करते हैं: http://localhost:3000/posts.json, तो आप सर्वर से भेजे गए एक जेसन ऑब्जेक्ट में अपनी सभी पोस्ट देखेंगे।

यह जावास्क्रिप्ट भारी अनुप्रयोग बनाने के लिए बहुत आसान है जिसे सर्वर से पीछे और पीछे जेसन पास करने की आवश्यकता है। यदि आप चाहते थे, तो आप आसानी से अपने रेल बैक-एंड पर एक जेसन एपीआई बना सकते हैं, और केवल एक दृश्य को पास कर सकते हैं - जैसे कि आपके पोस्ट कंट्रोलर के इंडेक्स व्यू। फिर आप डेटा को कुशल बनाने और अपना इंटरफ़ेस बनाने के लिए Jquery या Backbone (या दोनों) जैसे जावास्क्रिप्ट लाइब्रेरी का उपयोग कर सकते हैं। इन्हें एसिंक्रोनस यूआई कहा जाता है और वे वास्तव में लोकप्रिय हो रहे हैं (जीमेल एक है)। वे बहुत तेज़ हैं और अंत उपयोगकर्ता को वेब पर अधिक डेस्कटॉप जैसा अनुभव देते हैं। बेशक, यह आपके डेटा स्वरूपण का सिर्फ एक फायदा है।

इस लेखन की रेल 3 तरीका यह होगा:

class PostsController < ApplicationController 
     # GET /posts 
     # GET /posts.xml 


     respond_to :html, :xml, :json 

     def index 
     @posts = Post.all 

     respond_with(@posts) 
     end 

# 
# All your other REST methods 
# 

end 

वर्ग के शीर्ष पर respond_to :html, :xml, :json डाल करके, आप सभी स्वरूपों है कि आप अपने नियंत्रक अपने विचार करने के लिए भेजना चाहते घोषणा कर सकते हैं।

फिर, नियंत्रक विधि में, तुम सब करने की ज़रूरत respond_with (@whatever_object_you_have)

यह सिर्फ अपने कोड क्या रेल ऑटो उत्पन्न करता है की तुलना में थोड़ा अधिक सरल करता है।

आप इस के आंतरिक कामकाज के बारे में जानना चाहते हैं ...

मैं क्या समझ से, रेल निर्धारित करने के लिए क्या वास्तविक स्वरूप होने जा रहा है वस्तुओं introspects। 'स्वरूप' चर मूल्य इस आत्मनिरीक्षण पर आधारित है। रेल कुछ जानकारी के साथ पूरी तरह से कर सकते हैं। आप आश्चर्यचकित होंगे कि एक साधारण @ पोस्ट या कितना पोस्ट होगा।

उदाहरण के लिए, अगर मैं एक _user.html.erb आंशिक फ़ाइल है कि इस तरह देखा था:

_user.html।ERB

<li>  
    <%= link_to user.name, user %> 
</li> 

फिर, मेरी सूचकांक ध्यान में रखते हुए इस अकेले हैं रेल पता है कि यह 'उन' आंशिक खोजने के लिए और 'उन' वस्तुओं के सभी के माध्यम से पुनरावृति करने की जरूरत:

index.html .erb

<ul class="users"> 
    <%= render @users %>  
</ul> 

दिया जाएगा रेल पता है कि यह 'उपयोगकर्ता' आंशिक खोजने के लिए और 'उन' वस्तुओं के सभी के माध्यम से पुनरावृति करने की जरूरत:

तुम भी स्रोत का अवलोकन कर सकते हैं:: 1,363,210

आप इस ब्लॉग पोस्ट उपयोगी लग सकती https://github.com/rails/rails

+1

रेल 3 रास्ते पर अच्छी टिप। मैं अभी भी answer_to ब्लॉक के निचले हिस्से तक पहुंचने की कोशिश कर रहा हूं, और ब्लॉक तर्क क्या है | प्रारूप | पास हो जाता है – Cole

+3

अच्छा जवाब है लेकिन ब्लॉक में पारित प्रारूप चर के बारे में कुछ भी नहीं कहता है। दिए गए उदाहरण में format.html और format.json है - क्या इन दोनों को answer_to पर पास किया गया है और फिर जवाब दिया गया है कि यह तय करने के लिए कि उनके साथ क्या किया जाए? – Anthony

+0

जब 'respond_to' और' respond_with' पेश किया गया था? मैं ** रेल 2.3.5 ** का उपयोग कर रहा हूं और मुझे 'NoMethodError (अपरिभाषित विधि answer_to) ' – abbood

9

जो मैं जानता हूँ से, respond_to, एक विधि ActionController से जुड़ी है, इसलिए आप हर एक नियंत्रक में उपयोग कर सकते हैं , क्योंकि उनमें से सभी एक्शनकंट्रोलर से विरासत में हैं। ,

def respond_to(&block) 
    responder = Responder.new(self) 
    block.call(responder) 
    responder.respond 
end 

आप इसे एक block गुजर रहे हैं की तरह मैं यहाँ दिखाने:: यहाँ रेल respond_to विधि है

respond_to <<**BEGINNING OF THE BLOCK**>> do |format| 
    format.html 
    format.xml { render :xml => @whatever } 
end <<**END OF THE BLOCK**>> 

| प्रारूप | भाग तर्क है कि ब्लॉक की उम्मीद है, इसलिए respond_to विधि के अंदर हम इसका उपयोग कर सकते हैं। कैसे?

ठीक है, अगर आपको लगता है कि हम answer_to विधि में prefixed & के साथ ब्लॉक पास करते हैं, और हम उस ब्लॉक को प्रो के रूप में इलाज करने के लिए करते हैं। चूंकि तर्क में ".xml", ".html" है, इसलिए हम इसे कॉल करने के तरीके के रूप में उपयोग कर सकते हैं।

हम मूल रूप से answer_to कक्षा में क्या करते हैं, एक प्रतिक्रियाकर्ता वर्ग के उदाहरण के लिए ".html, .xml, .json" कॉल विधियां हैं।

+1

प्राप्त हो रहा है api दस्तावेज़ों में answer_to के स्रोत का स्रोत आपके द्वारा शामिल स्रोत से अलग है, और मुझे फेंक रहा था। आपका स्निपेट मुझे यह स्पष्ट करता है कि प्रारूप ब्लॉक तर्क को एक प्रतिक्रिया ऑब्जेक्ट पास किया जा रहा है। रेस्पॉन्डर प्रलेखन सवाल को जवाब देने लगता है, अब इसे पढ़ रहा है। – Cole

7

मैं समझना चाहता हूं कि प्रतिक्रिया_to ब्लॉक वास्तव में कैसे काम करता है। वैरिएबल का प्रकार प्रारूप है? प्रारूप ऑब्जेक्ट के .html और .json विधियां हैं?

यह समझने के लिए क्या format है, तो आपको पहले respond_to के लिए स्रोत पर दिखाई दे सकता है, लेकिन जल्दी आप पाएंगे कि retrieve_response_from_mimes के लिए कोड है वास्तव में क्या आप को देखने के लिए की जरूरत है।

यहाँ से, आप देखेंगे कि ब्लॉक कि respond_to को पारित किया गया था (अपने कोड में), वास्तव में कहा जाता है और Collector (जो ब्लॉक के भीतर format के रूप में संदर्भित किया जाता है) का एक उदाहरण के साथ पारित कर दिया है। कलेक्टर मूल रूप से mime types रेल के बारे में जानता है के आधार पर विधियों (मैं रेल स्टार्ट-अप पर विश्वास करता हूं) उत्पन्न करता है।

तो, हाँ, .html और .json कलेक्टर (उर्फ format) कक्षा पर परिभाषित विधियों (रनटाइम पर) हैं।

0

यह एक छोटे से पुरानी हो चुकी है, द्वारा रयान बिग इस यहाँ समझा एक महान काम करता है:

http://ryanbigg.com/2009/04/how-rails-works-2-mime-types-respond_to/

वास्तव में, यह थोड़ा और अधिक विस्तार से आप देख रहे थे हो सकता है। जैसा कि यह पता चला है, दृश्यों के पीछे बहुत कुछ चल रहा है, जिसमें यह समझने की आवश्यकता है कि एमआईएम प्रकार कैसे लोड हो जाते हैं।

158

मैं रूबी के लिए नया हूं और इस कोड पर फंस गया हूं। जिन हिस्सों को मैंने लटका दिया था, वे यहां दिए गए कुछ उत्तरों की तुलना में थोड़ा अधिक मौलिक थे। यह किसी की मदद कर सकता है या नहीं।

  • respond_to सुपरक्लास ActionController पर एक विधि है।
  • यह एक ब्लॉक लेता है, जो एक प्रतिनिधि की तरह है। ब्लॉक do से end तक, |format| के साथ ब्लॉक के लिए एक तर्क के रूप में है।
  • प्रतिक्रिया = आपके ब्लॉक को निष्पादित करने के लिए, format तर्क में एक उत्तरदाता को पारित करने के लिए।

http://api.rubyonrails.org/v4.1/classes/ActionController/Responder.html

  • Responder.html या .json के लिए एक विधि शामिल नहीं है, लेकिन हम इन तरीकों वैसे भी कहते हैं! इस भाग ने मुझे एक लूप के लिए फेंक दिया।
  • रूबी में method_missing नामक एक सुविधा है। यदि आप ऐसी विधि को कॉल करते हैं जो मौजूद नहीं है (जैसे json या html), रूबी इसके बजाय method_missing विधि कॉल करता है।

http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html

  • Responder वर्ग का उपयोग करता है अपने method_missing पंजीकरण का एक प्रकार के रूप में। जब हम 'जेसन' कहते हैं, तो हम जेसन को क्रमबद्ध करके .json एक्सटेंशन के अनुरोधों का जवाब देने के लिए कह रहे हैं। हमें html पर कॉल करने की आवश्यकता नहीं है, इसे डिफ़ॉल्ट तरीके से। एचटीएमएल अनुरोधों को संभालने के लिए कहने के लिए कोई तर्क नहीं है (सम्मेलनों और विचारों का उपयोग करके)।

यह इस तरह लिखा जा सकता है (जे एस की तरह स्यूडोकोड उपयोग करते हुए):

// get an instance to a responder from the base class 
var format = get_responder() 

// register html to render in the default way 
// (by way of the views and conventions) 
format.register('html') 

// register json as well. the argument to .json is the second 
// argument to method_missing ('json' is the first), which contains 
// optional ways to configure the response. In this case, serialize as json. 
format.register('json', renderOptions) 

इस भाग बिल्ली मेरे से बाहर उलझन में। मुझे अभी भी यह अनजान लगता है। रूबी इस तकनीक का काफी उपयोग करने लगता है। पूरी कक्षा (responder) विधि कार्यान्वयन बन जाती है। method_missing का लाभ उठाने के लिए, हमें कक्षा के एक उदाहरण की आवश्यकता है, इसलिए हम कॉलबैक पास करने के लिए बाध्य हैं जिसमें वे विधि-जैसी वस्तु को पास करते हैं। किसी ऐसे व्यक्ति के लिए जिसने 20 साल तक सी-जैसी भाषाओं में कोड किया है, यह मेरे लिए बहुत पीछे और अनजान है। यह बुरा नहीं है! लेकिन ऐसा कुछ है जो उस तरह की पृष्ठभूमि के साथ अपने सिर को पाने की ज़रूरत है, और मुझे लगता है कि ओपी के बाद क्या हो सकता है।

पेज। ध्यान दें कि RoR 4.2 respond_to में responders मणि में निकाला गया था।

+0

मैं पूरी तरह से सहमत हूं, रूबी स्रोत पढ़ने के लिए मुश्किल है। –

+0

धन्यवाद क्रेग, उस लिंक में वास्तव में उपयोगी जानकारी का एक टन भी था, मुझे यह नहीं पता था कि 'method_missing' के साथ कितना संभव है, क्योंकि आप इसे तर्क दे सकते हैं _and_ एक ब्लॉक! –

2

प्रत्युत्तर पंजीकरण (सूखी विद्रूप के जवाब देखें) भी आप इस तरह गंधा सामान करने की अनुमति देता के पीछे मेटा प्रोग्रामिंग:

def index 
    @posts = Post.all 

    respond_to do |format| 
    format.html # index.html.erb 
    format.json { render :json => @posts } 
    format.csv { render :csv => @posts } 
    format.js 
    end 
end 

सीएसवी लाइन to_csv कारण होगा प्रत्येक पोस्ट पर कहा जा करने के लिए जब आप यात्रा/posts.csv। इससे आपकी रेल साइट से डेटा को CSV (या कोई अन्य प्रारूप) के रूप में निर्यात करना आसान हो जाता है।

जेएस लाइन एक जावास्क्रिप्ट फ़ाइल /posts.js (या /posts.js.coffee) को प्रस्तुत/निष्पादित करने का कारण बन जाएगी। मैंने पाया है कि jQuery UI पॉप-अप का उपयोग करके अजाक्स सक्षम साइट बनाने के लिए हल्के वजन का तरीका बनना है।

1

किस प्रकार का चर प्रारूप है?

जावा पीओवी से, प्रारूप एक अज्ञात इंटरफेस का एक अपूर्ण है। इस इंटरफेस में प्रत्येक माइम प्रकार के लिए नामित एक विधि है। जब आप उन विधियों में से एक (इसे एक ब्लॉक पास करते हैं) का आह्वान करते हैं, तो यदि रेलों को लगता है कि उपयोगकर्ता उस सामग्री प्रकार को चाहता है, तो यह आपके ब्लॉक को बुलाएगा।

मोड़, ज़ाहिर है कि यह अज्ञात गोंद वस्तु वास्तव में एक इंटरफेस को लागू नहीं करती है - यह गतिशील रूप से विधि कॉल को पकड़ती है और अगर यह एक माइम प्रकार का नाम जानता है तो इसका काम करता है।

व्यक्तिगत रूप से, मुझे लगता है कि यह अजीब लग रहा है: आपके द्वारा पारित ब्लॉक निष्पादित किया गया है। यह स्वरूप लेबल और ब्लॉक के हैश में पास करने के लिए मुझे और अधिक समझ में आता है। लेकिन - ऐसा लगता है कि आरओआर में ऐसा कैसे हुआ, ऐसा लगता है।

0

"प्रारूप" आपका प्रतिक्रिया प्रकार है। उदाहरण के लिए, जेसन या एचटीएमएल हो सकता है। यह आपके विज़िटर को प्राप्त होने वाले आउटपुट का प्रारूप है।

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