Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Ruby

`Respond_to` बिना किसी दर्द के

जब आप रेल में मचान उत्पन्न करते हैं, तो आप सामान्य respond_to . देखेंगे ब्लॉक:

ऐप/कंट्रोलर/टास्क_कंट्रोलर.आरबी
  def destroy
    @task.destroy
    respond_to do |format|
      format.html { redirect_to tasks_url, notice: 'Task was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

लेकिन आपके कुछ कार्य, जैसे index , उनके पास नहीं है!

ऐप/कंट्रोलर/टास्क_कंट्रोलर.आरबी
  # GET /tasks
  # GET /tasks.json
  def index
    @tasks = Task.all
  end

यह तो बुरा हुआ। क्यों? अगर आप /tasks.txt hit दबाते हैं , और txt आपके ऐप द्वारा समर्थित नहीं है, आपको गलत त्रुटि मिलेगी:

ActionView::MissingTemplate (Missing template tasks/index, application/index with {:locale=>[:en], :formats=>[:text], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}

यह बिलकुल सही नहीं है। आपको क्लाइंट को बताना चाहिए कि वे एक ऐसे प्रारूप का अनुरोध कर रहे हैं जिसका आप समर्थन नहीं करते हैं, ऐसा नहीं है कि आपको सही फ़ाइल नहीं मिल रही है।

अगर यह एक UnknownFormat था त्रुटि, आप एक बेहतर प्रतिक्रिया कोड वापस कर सकते हैं। इसके बजाय, ये त्रुटियां अन्य, असंबंधित त्रुटियों के साथ मिल जाएंगी, और उन्हें संभालना वास्तव में कठिन होगा।

आप एक respond_to जोड़ सकते हैं अपने index . पर ब्लॉक करें क्रिया:

ऐप/कंट्रोलर/टास्क_कंट्रोलर.आरबी
  # GET /tasks
  # GET /tasks.json
  def index
    @tasks = Task.all
    respond_to do |format|
      format.html
      format.json
    end
  end

फिर, आपको वह अपवाद और त्रुटि कोड मिलेगा जिसकी आप अपेक्षा करते हैं:

Started GET "/tasks.txt" for 127.0.0.1 at 2014-11-03 22:05:12 -0800
Processing by TasksController#index as TEXT
Completed 406 Not Acceptable in 21ms

ActionController::UnknownFormat (ActionController::UnknownFormat):
  app/controllers/tasks_controller.rb:8:in `index'

काफी बेहतर। लेकिन अपने सभी नियंत्रकों को respond_to से भर देना पागल है। यह अन-रेल-ईश लगता है। यह DRY का उल्लंघन करता है। और यह आपको उस कार्य से विचलित करता है जो आपका नियंत्रक वास्तव में कर रहा है।

आप अभी भी खराब प्रारूपों को सही ढंग से संभालना चाहते हैं। तो आप क्या करते हैं?

एक respond_to शॉर्टकट

यदि आप अपनी वस्तुओं को प्रस्तुत करने के लिए कुछ विशेष नहीं कर रहे हैं, तो आप एक शॉर्टकट ले सकते हैं। अगर आप लिखते हैं:

ऐप/कंट्रोलर/टास्क_कंट्रोलर.आरबी
def index
  @tasks = Task.all
  respond_to :html, :json
end

यह उसी तरह काम करता है जैसे पूरा respond_to . लिखना index . में ब्लॉक करें . यह रेल को उन सभी प्रारूपों के बारे में बताने का एक छोटा तरीका है, जिनके बारे में आपकी कार्रवाई को पता है। और अगर अलग-अलग कार्रवाइयां अलग-अलग फ़ॉर्मैट का समर्थन करती हैं, तो बिना अधिक कोड के उन अंतरों को संभालने का यह एक अच्छा तरीका है।

नियंत्रक स्तर पर प्रारूपों को संभालें

आम तौर पर, हालांकि, आपके नियंत्रक में प्रत्येक क्रिया उसी . के साथ काम करेगी प्रारूप। अगर index json का जवाब देता है , तो new होगा , और create , और सब कुछ। तो अच्छा होगा यदि आपके पास respond_to हो जो संपूर्ण नियंत्रक को प्रभावित करेगा:

ऐप/कंट्रोलर/टास्क_कंट्रोलर.आरबी
class TasksController < ApplicationController
  before_action :set_task, only: [:show, :edit, :update, :destroy]
  respond_to :html, :json

  # GET /tasks
  # GET /tasks.json
  def index
    @tasks = Task.all
    respond_with(@tasks)
  end

और यह वास्तव में काम करता है:

Started GET "/tasks.txt" for 127.0.0.1 at 2014-11-03 22:17:37 -0800
Processing by TasksController#index as TEXT
Completed 406 Not Acceptable in 7ms

ActionController::UnknownFormat (ActionController::UnknownFormat):
  app/controllers/tasks_controller.rb:8:in `index'

ठीक उसी तरह की त्रुटि जिसकी हम उम्मीद कर रहे थे! और आपको इसे करने के लिए प्रत्येक क्रिया के साथ खिलवाड़ करने की आवश्यकता नहीं है।

कभी-कभी आप मॉडल की स्थिति के आधार पर अलग-अलग काम करना चाहेंगे। उदाहरण के लिए, create . के लिए , आप या तो फ़ॉर्म को पुनर्निर्देशित करेंगे या फिर से प्रस्तुत करेंगे, यह इस पर निर्भर करता है कि मॉडल मान्य है या नहीं।

रेल इसे संभाल सकते हैं। लेकिन आपको अभी भी यह बताना होगा कि आप किस वस्तु की जांच करना चाहते हैं, respond_with . के साथ . तो इसके बजाय:

ऐप/कंट्रोलर/टास्क_कंट्रोलर.आरबी
  def create
    @task = Task.new(task_params)

    respond_to do |format|
      if @task.save
        format.html { redirect_to @task, notice: 'Task was successfully created.' }
        format.json { render :show, status: :created, location: @task }
      else
        format.html { render :new }
        format.json { render json: @task.errors, status: :unprocessable_entity }
      end
    end
  end

आप लिख सकते हैं:

ऐप/कंट्रोलर/टास्क_कंट्रोलर.आरबी
  def create
    @task = Task.new(task_params)
    flash[:notice] = "Task was successfully created." if @task.save
    respond_with(@task)
  end

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

उत्तरदाता रत्न

रेल 4.2 में, एक पकड़ है:respond_with अब शामिल नहीं है। लेकिन आप इसे वापस प्राप्त कर सकते हैं यदि आप responders को स्थापित करते हैं मणि। और responders मणि अपने साथ कुछ और अच्छी सुविधाएँ लाता है।

आप फ़्लैश संदेशों को respond_with में सेट कर सकते हैं responders :flash आपके नियंत्रक के शीर्ष पर:

ऐप/कंट्रोलर/टास्क_कंट्रोलर.आरबी
class TasksController < ApplicationController
  responders :flash

आसानी से, आप अपनी स्थानीय फ़ाइलों में इन फ़्लैश संदेशों के लिए डिफ़ॉल्ट सेट कर सकते हैं।

साथ ही, यदि आपके पास responders है आपके Gemfile . में मणि और आप एक रेल मचान उत्पन्न करते हैं, जनरेटर respond_with . का उपयोग करके नियंत्रक बनाएगा respond_to . के बजाय :

ऐप/कंट्रोलर/टास्क_कंट्रोलर.आरबी
class TasksController < ApplicationController
  before_action :set_task, only: [:show, :edit, :update, :destroy]
  respond_to :html, :json
  
  def index
    @tasks = Task.all
    respond_with(@tasks)
  end

  def show
    respond_with(@task)
  end

  # ...

यह उन मचानों की तुलना में बहुत साफ है जिनके साथ रेल आती है।

और अंत में, यदि आप केवल विशिष्ट नियंत्रक क्रियाओं के लिए एक प्रारूप के साथ प्रतिक्रिया देना चाहते हैं, तो आप respond_to पर कॉल कर सकते हैं कई बार:

class TasksController < ApplicationController
  respond_to :html
  respond_to :js, only: :create
end

उस आखिरी टिप के लिए टिप्पणियों में जेरोइन वींक को धन्यवाद!

respond_with या respond_to ?

यदि आप विभिन्न प्रारूपों के लिए अलग-अलग जानकारी वापस करना चाहते हैं, तो आपके पास कुछ विकल्प हैं। नियंत्रक-स्तर respond_to respond_with . के साथ संयुक्त लघु नियंत्रक प्राप्त करने का एक शानदार तरीका है। लेकिन यह तब सबसे अधिक मदद करता है जब आपके सभी नियंत्रक कार्य एक ही प्रारूप में प्रतिक्रिया करते हैं, और उस तरह से कार्य करते हैं जिस तरह से रेल उनसे अपेक्षा करता है।

कभी-कभी, हालांकि, आप कुछ ऐसे कार्य करने में सक्षम होना चाहते हैं जो अलग तरह से कार्य करते हैं। वन-लाइनर respond_to उस स्थिति को संभालने के लिए बहुत अच्छा है।

यदि आपको अधिक नियंत्रण की आवश्यकता है, तो पूर्ण respond_to का उपयोग करें एक ब्लॉक के साथ, और आप अपनी इच्छानुसार प्रत्येक प्रारूप को संभाल सकते हैं।

इनमें से किसी के साथ, आपके द्वारा समर्थित प्रारूपों के अनुरोधों को सही त्रुटि मिलेगी। और आपका ऐप और उसके क्लाइंट दोनों बहुत कम भ्रमित होंगे।


  1. Amazon Day:अपनी सभी डिलीवरी एक ही दिन में पाएं

    अमेज़ॅन वर्षों से एक घरेलू नाम रहा है, लेकिन 2020 में अमेज़ॅन की बिक्री एक सर्वकालिक उच्च स्तर पर पहुंच गई। अमेज़ॅन के साथ पहले से कहीं अधिक खरीदारी करने वाले लोगों के साथ, कुछ एक समर्पित अमेज़ॅन दिवस बना रहे हैं, जहां वे उस सप्ताह के लिए अपने सभी पैकेज प्राप्त करते हैं। यह उन लोगों के लिए आदर्श है

  1. MongoDB संग्रह में सभी नाम प्राप्त करें

    मूल रूप से 18 जनवरी, 2019 को ObjectRocket.com/blog पर प्रकाशित हुआ। अपने स्कीमा को सत्यापित करने के लिए, फ़ील्ड में टाइपो के लिए डीबग करें, या ऐसे फ़ील्ड ढूंढें जिन्हें आपको सेट नहीं करना चाहिए, आपको अपने MongoDB® संग्रह में सभी कुंजियों की समझ की आवश्यकता है। ObjectRocket सहित कई MongoDB-as-a-S

  1. MongoDB संग्रह में सभी कुंजियों के नाम प्राप्त करें

    अपने स्कीमा को सत्यापित करने के लिए, फ़ील्ड में टाइपो के लिए डीबग करें, या ऐसे फ़ील्ड ढूंढें जिन्हें सेट नहीं किया जाना चाहिए, आपको अपने MongoDB संग्रह में सभी कुंजियों की समझ प्राप्त करने की आवश्यकता होगी। कई MongoDB-as-a-service कंपनियाँ UI में इस अधिकार को करने का एक आसान तरीका प्रदान करती हैं,