আপনি যখন Rails এ একটি স্ক্যাফোল্ড তৈরি করবেন, তখন আপনি স্বাভাবিক 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 হিট করেন , এবং 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 লঙ্ঘন করে। এবং এটি আপনাকে আপনার কন্ট্রোলার যে কাজটি করছে তা থেকে বিভ্রান্ত করে।
আপনি এখনও সঠিকভাবে খারাপ বিন্যাস পরিচালনা করতে চান. তাহলে আপনি কি করেন?
A 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
এইভাবে, আপনি যে ফর্ম্যাটে সাড়া দেন সেগুলি থেকে আপনি আপনার কোডকে আলাদা করুন। আপনি রেলকে একবার বলতে পারেন আপনি যে ফরম্যাটগুলি পরিচালনা করতে চান। প্রতিটি কর্মে আপনাকে সেগুলি পুনরাবৃত্তি করতে হবে না৷৷
প্রতিক্রিয়াকারী রত্ন
Rails 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
সেই শেষ টিপের জন্য মন্তব্যে Jeroen Weeink কে ধন্যবাদ!
respond_with অথবা respond_to ?
আপনি যদি বিভিন্ন ফরম্যাটের জন্য বিভিন্ন তথ্য ফেরত দিতে চান, আপনার কাছে কয়েকটি বিকল্প আছে। কন্ট্রোলার-লেভেল respond_to respond_with এর সাথে মিলিত সংক্ষিপ্ত কন্ট্রোলার পেতে একটি দুর্দান্ত উপায়। কিন্তু যখন আপনার সমস্ত কন্ট্রোলার ক্রিয়া একই বিন্যাসে সাড়া দেয় এবং রেল তাদের প্রত্যাশা করে সেভাবে কাজ করে তখন এটি সবচেয়ে বেশি সাহায্য করে৷
কখনও কখনও, যদিও, আপনি কয়েকটি ক্রিয়া করতে সক্ষম হতে চান যা ভিন্নভাবে কাজ করে। ওয়ান-লাইনার respond_to সেই পরিস্থিতি সামাল দেওয়ার জন্য দুর্দান্ত৷
আপনার আরও নিয়ন্ত্রণের প্রয়োজন হলে, সম্পূর্ণ respond_to ব্যবহার করুন একটি ব্লক দিয়ে, এবং আপনি চাইলে প্রতিটি ফরম্যাট পরিচালনা করতে পারেন।
এইগুলির যেকোন একটির সাথে, আপনি সমর্থন করেন না এমন ফর্ম্যাটের জন্য অনুরোধগুলি সঠিক ত্রুটি পাবে৷ এবং আপনার অ্যাপ এবং এর ক্লায়েন্ট উভয়ই অনেক কম বিভ্রান্ত হবে।