Ruby on Rails 5.2 - ActionController::MimeResponds

मॉड्यूल ActionController :: MimeResponds




ruby

मॉड्यूल ActionController :: MimeResponds

सार्वजनिक प्रवृत्ति के तरीके

response_to (* mimes) {| कलेक्टर | ...} स्रोत दिखाएं
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 193
def respond_to(*mimes)
  raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?

  collector = Collector.new(mimes, request.variant)
  yield collector if block_given?

  if format = collector.negotiate_format(request)
    _process_format(format)
    _set_rendered_content_type format
    response = collector.response
    response.call if response
  else
    raise ActionController::UnknownFormat
  end
end

वेब-सेवा समर्थन के बिना, एक कार्रवाई जो लोगों की सूची प्रदर्शित करने के लिए डेटा एकत्र करती है, वह कुछ इस तरह दिख सकती है:

def index
  @people = Person.all
end

यह क्रिया सभी प्रारूपों के लिए संक्षिप्त रूप से प्रतिक्रिया देती है, लेकिन स्वरूपों को श्वेतसूची में भी रखा जा सकता है:

def index
  @people = Person.all
  respond_to :html, :js
end

यहाँ एक ही क्रिया है, जिसमें वेब-सेवा समर्थन बेक किया गया है:

def index
  @people = Person.all

  respond_to do |format|
    format.html
    format.js
    format.xml { render xml: @people }
  end
end

जो कहता है वह यह है, "यदि ग्राहक इस कार्रवाई के जवाब में HTML या JS चाहता है, तो ठीक वैसे ही जवाब दें जैसा कि हमने पहले दिया था, लेकिन यदि ग्राहक XML चाहता है, तो उन्हें XML प्रारूप में लोगों की सूची लौटाएं।" क्लाइंट द्वारा प्रस्तुत HTTP स्वीकार हेडर से प्रतिक्रिया स्वरूप।)

मान लें कि आपके पास एक ऐसी कार्रवाई है जो एक नया व्यक्ति जोड़ती है, वैकल्पिक रूप से अपनी कंपनी (नाम से) बना रही है यदि यह पहले से मौजूद नहीं है, तो वेब-सेवाओं के बिना, यह इस तरह दिख सकता है:

def create
  @company = Company.find_or_create_by(name: params[:company][:name])
  @person  = @company.people.create(params[:person])

  redirect_to(person_list_url)
end

यहाँ एक ही क्रिया है, जिसमें वेब-सेवा समर्थन बेक किया गया है:

def create
  company  = params[:person].delete(:company)
  @company = Company.find_or_create_by(name: company[:name])
  @person  = @company.people.create(params[:person])

  respond_to do |format|
    format.html { redirect_to(person_list_url) }
    format.js
    format.xml  { render xml: @person.to_xml(include: @company) }
  end
end

यदि क्लाइंट HTML चाहता है, तो हम उन्हें वापस व्यक्ति सूची में भेज देते हैं। यदि वे जावास्क्रिप्ट चाहते हैं, तो यह एक अजाक्स अनुरोध है और हम इस कार्रवाई से जुड़े जावास्क्रिप्ट टेम्पलेट को प्रस्तुत करते हैं। अंत में, यदि ग्राहक XML चाहता है, तो हम बनाए गए व्यक्ति को XML के रूप में प्रस्तुत करते हैं, लेकिन एक मोड़ के साथ: हम प्रस्तुत किए गए XML में व्यक्ति की कंपनी को भी शामिल करते हैं, इसलिए आपको ऐसा कुछ मिलता है:

<person>
  <id>...</id>
  ...
  <company>
    <id>...</id>
    <name>...</name>
    ...
  </company>
</person>

हालाँकि, नोट उस कार्रवाई के शीर्ष पर अतिरिक्त बिट:

company  = params[:person].delete(:company)
@company = Company.find_or_create_by(name: company[:name])

इसका कारण यह है कि आने वाले XML दस्तावेज़ (यदि एक वेब-सेवा अनुरोध प्रक्रिया में है) में केवल एक रूट-नोड हो सकता है। इसलिए, हमें चीजों को पुनर्व्यवस्थित करना होगा ताकि अनुरोध इस तरह दिखाई दे (url-encoded):

person[name]=...&person[company][name]=...&...

और, इस तरह (xml- एन्कोडेड):

<person>
  <name>...</name>
  <company>
    <name>...</name>
  </company>
</person>

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

ध्यान दें कि आप अपने स्वयं के XML पैरामीटर पार्सर को परिभाषित कर सकते हैं जो आपको एक ही अनुरोध में कई संस्थाओं का वर्णन करने की अनुमति देगा (यानी, सभी को एक रूट नोड में लपेटकर), लेकिन यदि आप बस प्रवाह के साथ जाते हैं और रेल की चूक स्वीकार करते हैं, जीवन बहुत आसान हो जाएगा।

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

Mime::Type.register "image/jpg", :jpg

any का उपयोग करके आपको विभिन्न स्वरूपों के लिए एक सामान्य ब्लॉक निर्दिष्ट करने की अनुमति देता है:

def index
  @people = Person.all

  respond_to do |format|
    format.html
    format.any(:xml, :json) { render request.format.to_sym => @people }
  end
end

ऊपर के उदाहरण में, यदि प्रारूप xml है, तो यह प्रस्तुत करेगा:

render xml: @people

या अगर प्रारूप json है:

render json: @people

प्रारूप के विभिन्न प्रकार हो सकते हैं।

अनुरोध संस्करण, अनुरोध प्रारूप का एक विशेषज्ञता है, जैसे :tablet , :phone , या :desktop

हम अक्सर फोन, टैबलेट और डेस्कटॉप ब्राउज़र के लिए अलग-अलग HTML / json / xml टेम्प्लेट प्रस्तुत करना चाहते हैं। वेरिएंट इसे आसान बनाते हैं।

आप पहले वाले संस्करण में वेरिएंट सेट कर सकते हैं:

request.variant = :tablet if request.user_agent =~ /iPad/

क्रियाओं के प्रतिरूपों का उत्तर वैसे ही दें जैसे आप स्वरूपों का उत्तर देते हैं:

respond_to do |format|
  format.html do |variant|
    variant.tablet # renders app/views/projects/show.html+tablet.erb
    variant.phone { extra_setup; render ... }
    variant.none  { special_setup } # executed only if there is no variant set
  end
end

प्रत्येक प्रारूप और संस्करण के लिए अलग टेम्पलेट प्रदान करें:

app/views/projects/show.html.erb
app/views/projects/show.html+tablet.erb
app/views/projects/show.html+phone.erb

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

respond_to do |format|
  format.js         { render "trash" }
  format.html.phone { redirect_to progress_path }
  format.html.none  { render "trash" }
end

वेरिएंट any भी सामान्य / all ब्लॉक का समर्थन करता है जो प्रारूप हैं।

यह दोनों इनलाइन के लिए काम करता है:

respond_to do |format|
  format.html.any   { render html: "any"   }
  format.html.phone { render html: "phone" }
end

और ब्लॉक सिंटैक्स:

respond_to do |format|
  format.html do |variant|
    variant.any(:tablet, :phablet){ render html: "any" }
    variant.phone { render html: "phone" }
  end
end

आप विभिन्न प्रकारों की एक सरणी भी सेट कर सकते हैं:

request.variant = [:tablet, :phone]

यह प्रारूप और MIME प्रकार की बातचीत के समान काम करेगा। यदि कोई :tablet संस्करण घोषित नहीं किया गया है, तो :phone संस्करण का उपयोग किया जाएगा:

respond_to do |format|
  format.html.none
  format.html.phone # this gets rendered
end