रेलें: answer_to ब्लॉक कैसे काम करती है?


211

मैं रेलिंग गाइड के साथ शुरुआत कर रहा हूं और धारा 6.7 के साथ भ्रमित हो रहा हूं । एक पाड़ पैदा करने के बाद मुझे अपने नियंत्रक में निम्नलिखित ऑटो-जनरेटेड ब्लॉक मिलते हैं:

def index
  @posts = Post.all

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

मैं यह समझना चाहता हूं कि response_to ब्लॉक वास्तव में कैसे काम करता है। प्रारूप किस प्रकार का है? । Html और प्रारूप वस्तु के .json तरीके हैं? प्रलेखन के लिए

ActionController::MimeResponds::ClassMethods::respond_to

इस सवाल का जवाब नहीं है।


यह अच्छा होगा अगर मैं ActionController :: MimeResponds :: ClassMethods :: response_to पर api.rubyonrails.org के लिए दस्तावेज़ से लिंक कर सकता हूं, लेकिन यह सीधे हाइपरलिंक को पसंद नहीं करता है ...
कोल

response_to कॉल का अंत लेता है (जैसे blah.html, blah.json, आदि) और निर्दिष्ट दृश्य से मेल खाता है। अन्य प्रतिसाद के आधार पर XML, CSV और कई अन्य अनुप्रयोग हो सकते हैं।
स्कॉटजेशिया

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

मुझे नहीं लगता कि विस्तार (एक्सएमएल, एचटीएमएल, आदि) नक्शे एक दृश्य के लिए। यदि आप डिफ़ॉल्ट रेंडरिंग चुनते हैं ( format.html- कोई तर्क नहीं) तो यह एक दृश्य (HTML होने की उम्मीद) चुनने के लिए सम्मेलनों (URL और HTTP क्रिया पर आधारित) का उपयोग करेगा। उत्तरदाता (प्रारूप) को निर्देश दिया जाता है कि वह विचारों और सम्मेलनों का उपयोग करने के बजाय , json को क्रमबद्ध करके .json में समाप्त होने वाले URL को प्रस्तुत करे ।
क्रेग सेलेस्टे

जवाबों:


189

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

  • respond_toसुपरक्लास पर एक विधि है ActionController
  • यह एक ब्लॉक लेता है, जो एक प्रतिनिधि की तरह है। ब्लॉक doतब तक है end, जब तक |format|कि ब्लॉक के तर्क के रूप में।
  • response_to अपने ब्लॉक को निष्पादित करता है, एक उत्तरदाता को 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' कहते हैं, तो हम इसे json को क्रमबद्ध करके .json एक्सटेंशन के साथ अनुरोधों का जवाब देने के लिए कह रहे हैं। हमें htmlयह बताने के लिए कोई तर्क के साथ कॉल करने की आवश्यकता है कि डिफ़ॉल्ट तरीके से .html अनुरोधों (सम्मेलनों और विचारों का उपयोग करके)।

इसे इस तरह लिखा जा सकता है (JS-like pseudocode का उपयोग करके):

// 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में उत्तरदाताओं मणि में निकाला गया था ।


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

2
Responder वर्ग में पंजीकरण तंत्र के रूप में method_missing () के उपयोग को समझाने के लिए सर्वश्रेष्ठ उत्तर! मैं भी इस कोड को लेकर बहुत उलझन में था ।
एलन इवेंजेलिस्टा

1
6 मचान respond_toजनरेटर्स लगता है कि नियंत्रकों के साथ कोड का उत्पादन होता है , बिना उत्तरदाताओं के जेमाइल में मौजूद मणि। शायद respond_toउत्तरदाताओं के मणि में निकाले जाने के बारे में थोड़ा बदल दिया गया है?
कासिम

106

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

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

आपके उदाहरण में ब्लॉक डेटा को फ़ॉर्मेट कर रहा है - ब्लॉक में एक 'फॉर्मेट' पैरामाटर में पास करके - जब भी कोई ब्राउज़र html या json डेटा के लिए अनुरोध करता है, तो उसे कंट्रोलर से दृश्य में भेजा जाएगा।

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

यह जावास्क्रिप्ट भारी अनुप्रयोगों को बनाने के लिए बहुत आसान है जो सर्वर से आगे और पीछे से पास करने की आवश्यकता है। यदि आप चाहते हैं, तो आप आसानी से अपने रेल के बैक-एंड पर एक 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कक्षा के शीर्ष पर रखकर , आप उन सभी स्वरूपों को घोषित कर सकते हैं जिन्हें आप अपने नियंत्रक को अपने विचारों को भेजना चाहते हैं।

फिर, कंट्रोलर मेथड में, आपको केवल करना होगा response_with (@whatever_object_you_have)

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

अगर आप इस के अंदरूनी कामकाज के बारे में जानना चाहते हैं ...

मैं जो समझ रहा हूं, उससे यह पता चलता है कि वास्तविक स्वरूप क्या होने जा रहा है, यह निर्धारित करने के लिए रेल वस्तुओं का अंतःसंबंध करता है। 'प्रारूप' चर मूल्य इस आत्मनिरीक्षण पर आधारित है। थोड़ी जानकारी के साथ रेल पूरी तरह से कर सकती है। आपको आश्चर्य होगा कि एक सरल @ पोस्ट या कितनी दूर: पोस्ट जाएगी।

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

_user.html.erb

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

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

index.html.erb

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

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

आपको यह ब्लॉग पोस्ट उपयोगी लग सकता है: http://archives.ryandaigle.com/articles/2009/8/6/what-s-new-in-edge-rails-cleaner-restful-controllers-w-respond-with

आप स्रोत का उपयोग भी कर सकते हैं: https://github.com/rails/rails


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

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

कब respond_toऔर respond_withशुरू किया गया था ? मैं उपयोग कर रहा हूँ रेल 2.3.5 और मैं हो रही हैNoMethodError (undefined method respond_to)
abbood

10

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

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

आप इसे ब्लॉक कर रहे हैं , जैसे मैं यहां दिखाता हूं:

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

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

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

हम मूल रूप से response_to वर्ग में कॉल करने के तरीके ".html, .xml, .json" को एक रिस्पॉन्डर क्लास के उदाहरण के लिए कहते हैं।


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

7

मैं यह समझना चाहता हूं कि response_to ब्लॉक वास्तव में कैसे काम करता है। प्रारूप किस प्रकार का है? प्रारूप वस्तु के .html और .json विधियाँ हैं?

यह समझने के लिए कि formatआप पहले किस स्रोत के लिए देख सकते हैं respond_to, लेकिन जल्दी से आपको पता चलेगा कि वास्तव में आपको जो देखने की आवश्यकता है वह पुनर्प्राप्त करने के लिए कोड है_response_from_mimes

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

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


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

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

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


1

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

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

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

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


1

यह थोड़ा पुराना है, रयान बिग द्वारा यह समझाने के लिए एक महान काम करता है:

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

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


0

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


0

एक और चीज है जिसके बारे में आपको पता होना चाहिए - MIME।

यदि आपको MIME प्रकार का उपयोग करने की आवश्यकता है और यह डिफ़ॉल्ट रूप से समर्थित नहीं है, तो आप अपने स्वयं के संचालकों को config / initializers / mime_types.rb में पंजीकृत कर सकते हैं:

Mime::Type.register "text/markdown", :markdown

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