আমি রেলগুলিতে একটি 404 পৃষ্ঠা 'নকল' করতে চাই। পিএইচপি-তে, আমি কেবল ত্রুটি কোড সহ একটি শিরোনাম পাঠাব:
header("HTTP/1.0 404 Not Found");
এটি কীভাবে পেরেলগুলি দিয়ে করা হয়?
আমি রেলগুলিতে একটি 404 পৃষ্ঠা 'নকল' করতে চাই। পিএইচপি-তে, আমি কেবল ত্রুটি কোড সহ একটি শিরোনাম পাঠাব:
header("HTTP/1.0 404 Not Found");
এটি কীভাবে পেরেলগুলি দিয়ে করা হয়?
উত্তর:
404 নিজেকে রেন্ডার করবেন না, এর কোনও কারণ নেই; রেলগুলির মধ্যে ইতিমধ্যে অন্তর্নির্মিত এই কার্যকারিতা রয়েছে। আপনি যদি 404 পৃষ্ঠা প্রদর্শন করতে চান তবে একটি render_404
পদ্ধতি তৈরি করুন (বা not_found
যেমন আমি এটি বলেছিলাম) এর ApplicationController
মতো:
def not_found
raise ActionController::RoutingError.new('Not Found')
end
এছাড়াও হ্যান্ডলগুলি পাগল AbstractController::ActionNotFound
, এবং ActiveRecord::RecordNotFound
একই ভাবে।
এটি দুটি জিনিস আরও ভাল করে:
1) এটি rescue_from
404 পৃষ্ঠাটি রেন্ডার করতে হ্যান্ডলারে অন্তর্নির্মিত রেলগুলি ব্যবহার করে এবং 2) এটি আপনার কোডটির সম্পাদনকে বাধা দেয়, আপনাকে সুন্দর কাজগুলি করতে দেয়:
user = User.find_by_email(params[:email]) or not_found
user.do_something!
কুরুচিপূর্ণ শর্তাধীন বিবৃতি না লিখে।
বোনাস হিসাবে, পরীক্ষাগুলি পরিচালনা করাও অত্যন্ত সহজ। উদাহরণস্বরূপ, আরএসপেক একীকরণ পরীক্ষায়:
# RSpec 1
lambda {
visit '/something/you/want/to/404'
}.should raise_error(ActionController::RoutingError)
# RSpec 2+
expect {
get '/something/you/want/to/404'
}.to raise_error(ActionController::RoutingError)
এবং সর্বনিম্ন:
assert_raises(ActionController::RoutingError) do
get '/something/you/want/to/404'
end
অথবা রেলগুলি থেকে 404 রেন্ডার থেকে আরও তথ্য পড়ুন কোনও নিয়ামক পদক্ষেপ থেকে পাওয়া যায় নি
ActionController::RecordNotFound
ভালো বিকল্প বলে মনে হচ্ছে ?
expect { visit '/something/you/want/to/404' }.to raise_error(ActionController::RoutingError)
মাধ্যমে / stackoverflow.com/a/1722839/993890
একটি 404 শিরোনাম ফিরিয়ে দিতে, :status
রেন্ডার পদ্ধতির জন্য কেবল বিকল্পটি ব্যবহার করুন।
def action
# here the code
render :status => 404
end
আপনি যদি মান 404 পৃষ্ঠাটি রেন্ডার করতে চান তবে আপনি কোনও পদ্ধতিতে বৈশিষ্ট্যটি বের করতে পারেন।
def render_404
respond_to do |format|
format.html { render :file => "#{Rails.root}/public/404", :layout => false, :status => :not_found }
format.xml { head :not_found }
format.any { head :not_found }
end
end
এবং এটি আপনার কর্ম হিসাবে কল
def action
# here the code
render_404
end
আপনি যদি ক্রিয়াটি ত্রুটি পৃষ্ঠাটি রেন্ডার এবং বন্ধ করতে চান তবে কেবল একটি রিটার্ন স্টেটমেন্ট ব্যবহার করুন।
def action
render_404 and return if params[:something].blank?
# here the code that will never be executed
end
এছাড়াও মনে রাখবেন যে রেলগুলি কিছু অ্যাক্টিভেকর্ড ত্রুটিগুলি উদ্ধার করে, যেমন ActiveRecord::RecordNotFound
404 ত্রুটি পৃষ্ঠা প্রদর্শন করে।
এর অর্থ এই ক্রিয়াটি নিজেকে উদ্ধার করার দরকার নেই
def show
user = User.find(params[:id])
end
User.find
ActiveRecord::RecordNotFound
যখন ব্যবহারকারী উপস্থিত না থাকে তখন উত্থাপন করে। এটি একটি খুব শক্তিশালী বৈশিষ্ট্য। নীচের কোডটি দেখুন
def show
user = User.find_by_email(params[:email]) or raise("not found")
# ...
end
আপনি চেকটি রেলগুলিতে অর্পণ করে এটিকে সহজ করতে পারেন। সহজভাবে ঠুং শব্দ সংস্করণ ব্যবহার করুন।
def show
user = User.find_by_email!(params[:email])
# ...
end
স্টিভেন সোরোকার জমা দেওয়া নতুন নির্বাচিত উত্তরটি নিকটে, তবে সম্পূর্ণ নয়। পরীক্ষা নিজেই এই সত্যটি লুকিয়ে রাখে যে এটি সত্য 404 ফিরিয়ে দিচ্ছে না - এটি 200 - "সাফল্য" এর একটি স্থিতি ফিরিয়ে দিচ্ছে। মূল উত্তরটি কাছাকাছি ছিল, তবে বিন্যাসটি এমনভাবে সরবরাহ করার চেষ্টা করেছিল যেন কোনও ব্যর্থতা ঘটেনি। এটি সবকিছু স্থির করে:
render :text => 'Not Found', :status => '404'
আরএসপেক এবং কাঁদা ম্যাথার্স ব্যবহার করে 404 ফেরত প্রত্যাশা করি এমন কিছুর জন্য এখানে আমার একটি সাধারণ পরীক্ষার সেট রয়েছে:
describe "user view" do
before do
get :show, :id => 'nonsense'
end
it { should_not assign_to :user }
it { should respond_with :not_found }
it { should respond_with_content_type :html }
it { should_not render_template :show }
it { should_not render_with_layout }
it { should_not set_the_flash }
end
এই স্বাস্থ্যকর প্যারানোয়াটি আমাকে অন্য বিষয়গুলি পীচি লাগলে সামগ্রী-ধরণের অমিলটি স্পট করার অনুমতি দেয় :) আমি এই সমস্ত উপাদানগুলির জন্য যাচাই করি: নির্ধারিত ভেরিয়েবল, প্রতিক্রিয়া কোড, প্রতিক্রিয়া সামগ্রী প্রকার, টেমপ্লেট রেন্ডার, লেআউট রেন্ডার, ফ্ল্যাশ বার্তা।
আমি কখনও কখনও কখনও কঠোরভাবে এইচটিএমএল এমন অ্যাপ্লিকেশনগুলিতে সামগ্রী প্রকারের চেক এড়িয়ে যাব। সর্বোপরি, "একজন সন্দিহান সমস্ত দারাগুলি পরীক্ষা করে" :)
http://dilbert.com/strips/comic/1998-01-20/
এফওয়াইআই: আমি নিয়ামকের মধ্যে যা ঘটে চলেছে তার জন্য পরীক্ষার প্রস্তাব দিই না, "" should_raise "। আপনি যা যত্নশীল তা আউটপুট। উপরের আমার পরীক্ষাগুলি আমাকে বিভিন্ন সমাধানের চেষ্টা করার অনুমতি দিয়েছে এবং সমাধানগুলি কোনও ব্যতিক্রম, বিশেষ উপস্থাপনা ইত্যাদির উত্থাপন করছে কিনা তা পরীক্ষাগুলি একই থাকে the
render :text => 'Not Found', :status => :not_found
।
config.consider_all_requests_local
প্যারামিটারটি সম্ভবত আপনার environments/development.rb
ফাইলে সেট করা আছে । মঞ্চায়ন / উত্পাদনের ক্ষেত্রে গৃহীত সমাধানে বর্ণিত হিসাবে আপনি যদি কোনও ত্রুটি বাড়িয়ে থাকেন তবে আপনি অবশ্যই একটি 200 নয় একটি 404 পাবেন
আপনি রেন্ডার ফাইলটিও ব্যবহার করতে পারেন:
render file: "#{Rails.root}/public/404.html", layout: false, status: 404
আপনি যেখানে লেআউটটি ব্যবহার করতে বা চয়ন করতে পারেন।
আর একটি বিকল্প এটি নিয়ন্ত্রণ করতে ব্যতিক্রমগুলি ব্যবহার করা হয়:
raise ActiveRecord::RecordNotFound, "Record not found."
নির্বাচিত উত্তরটি 3.3+ রেলগুলিতে কাজ করে না কারণ ত্রুটি হ্যান্ডলারটি মিডওয়্যারটিতে স্থানান্তরিত হয়েছিল ( গিথুব সমস্যাটি দেখুন )।
আমি যে সমাধানটি পেয়েছি তাতে আমি বেশ খুশি Here
ইন ApplicationController
:
unless Rails.application.config.consider_all_requests_local
rescue_from Exception, with: :handle_exception
end
def not_found
raise ActionController::RoutingError.new('Not Found')
end
def handle_exception(exception=nil)
if exception
logger = Logger.new(STDOUT)
logger.debug "Exception Message: #{exception.message} \n"
logger.debug "Exception Class: #{exception.class} \n"
logger.debug "Exception Backtrace: \n"
logger.debug exception.backtrace.join("\n")
if [ActionController::RoutingError, ActionController::UnknownController, ActionController::UnknownAction].include?(exception.class)
return render_404
else
return render_500
end
end
end
def render_404
respond_to do |format|
format.html { render template: 'errors/not_found', layout: 'layouts/application', status: 404 }
format.all { render nothing: true, status: 404 }
end
end
def render_500
respond_to do |format|
format.html { render template: 'errors/internal_server_error', layout: 'layouts/application', status: 500 }
format.all { render nothing: true, status: 500}
end
end
এবং ইন application.rb
:
config.after_initialize do |app|
app.routes.append{ match '*a', :to => 'application#not_found' } unless config.consider_all_requests_local
end
এবং আমার সংস্থানগুলিতে (দেখান, সম্পাদনা করুন, আপডেট করুন, মুছুন):
@resource = Resource.find(params[:id]) or not_found
এটি অবশ্যই উন্নত করা যেতে পারে, তবে কমপক্ষে, মূল রেল ফাংশনগুলিকে ওভাররাইড না করে আমার কাছে নোট_ফাউন্ড এবং ইন্টারনাল_অরারের পক্ষে বিভিন্ন মতামত রয়েছে।
|| not_found
অংশটি প্রয়োজন নেই , কেবল কল করুন find!
(ব্যাংকে লক্ষ্য করুন) এবং এটি অ্যাক্টিভেকর্ড :: রেকর্ডনটফাউন্ড নিক্ষেপ করবে যখন সংস্থানটি পুনরুদ্ধার করা যায় না। এছাড়াও, যদি শর্তে অ্যাক্টিভেকর্ড :: রেকর্ডনটফাউন্ড অ্যারেতে যুক্ত করুন।
StandardError
এবং না Exception
, কেবল ক্ষেত্রেই। প্রকৃতপক্ষে আমি স্ট্যান্ডার্ড 500 স্ট্যাটিক পৃষ্ঠাটি ছেড়ে দেব এবং একেবারেই কাস্টম ব্যবহার render_500
করব না, এর অর্থ আমি স্পষ্টভাবে rescue_from
404 এর সাথে সম্পর্কিত ত্রুটির অ্যারে করব
এগুলি আপনাকে সাহায্য করবে ...
অ্যাপ্লিকেশন নিয়ামক
class ApplicationController < ActionController::Base
protect_from_forgery
unless Rails.application.config.consider_all_requests_local
rescue_from ActionController::RoutingError, ActionController::UnknownController, ::AbstractController::ActionNotFound, ActiveRecord::RecordNotFound, with: lambda { |exception| render_error 404, exception }
end
private
def render_error(status, exception)
Rails.logger.error status.to_s + " " + exception.message.to_s
Rails.logger.error exception.backtrace.join("\n")
respond_to do |format|
format.html { render template: "errors/error_#{status}",status: status }
format.all { render nothing: true, status: status }
end
end
end
ত্রুটিগুলি নিয়ন্ত্রণকারী
class ErrorsController < ApplicationController
def error_404
@not_found_path = params[:not_found]
end
end
মতামত / ত্রুটি / error_404.html.haml
.site
.services-page
.error-template
%h1
Oops!
%h2
404 Not Found
.error-details
Sorry, an error has occured, Requested page not found!
You tried to access '#{@not_found_path}', which is not a valid page.
.error-actions
%a.button_simple_orange.btn.btn-primary.btn-lg{href: root_path}
%span.glyphicon.glyphicon-home
Take Me Home
<%= render file: 'public/404', status: 404, formats: [:html] %>
404 ত্রুটি পৃষ্ঠায় আপনি যে পৃষ্ঠায় রেন্ডার করতে চান তা কেবল এই পৃষ্ঠায় যুক্ত করুন এবং আপনার কাজ শেষ হয়েছে।
আমি প্রশাসক নন এমন যে কোনও লগ ইন হওয়া ব্যবহারকারীর জন্য একটি 'সাধারণ' 404 নিক্ষেপ করতে চেয়েছিলাম, সুতরাং আমি এই জাতীয় 5 টির মতো লিখেছিলাম:
class AdminController < ApplicationController
before_action :blackhole_admin
private
def blackhole_admin
return if current_user.admin?
raise ActionController::RoutingError, 'Not Found'
rescue ActionController::RoutingError
render file: "#{Rails.root}/public/404", layout: false, status: :not_found
end
end
routes.rb
get '*unmatched_route', to: 'main#not_found'
main_controller.rb
def not_found
render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
end
ত্রুটি পরিচালনার পরীক্ষা করার জন্য, আপনি এর মতো কিছু করতে পারেন:
feature ErrorHandling do
before do
Rails.application.config.consider_all_requests_local = false
Rails.application.config.action_dispatch.show_exceptions = true
end
scenario 'renders not_found template' do
visit '/blah'
expect(page).to have_content "The page you were looking for doesn't exist."
end
end
আপনি যদি বিভিন্নভাবে বিভিন্ন 404 টি পরিচালনা করতে চান তবে সেগুলি আপনার নিয়ামকগুলিতে ধরা বিবেচনা করুন। এটি আপনাকে বিভিন্ন ব্যবহারকারী গোষ্ঠী দ্বারা উত্পাদিত 404 টির সংখ্যা ট্র্যাক করার, ব্যবহারকারীদের সাথে কী ভুল হয়েছে / ব্যবহারকারী অভিজ্ঞতার কোন অংশে টুইঙ্কের প্রয়োজন হতে পারে, এ / বি পরীক্ষার ব্যবস্থা ইত্যাদির সাহায্যে যোগাযোগের সহায়তা দেওয়ার মতো জিনিসগুলি করতে অনুমতি দেবে etc.
আমি অ্যাপ্লিকেশন নিয়ন্ত্রণকারীটিতে বেস লজিকটি এখানে রেখেছি, তবে এটি কেবলমাত্র একটি নিয়ামকের জন্য বিশেষ যুক্তি রাখতে আরও নির্দিষ্ট নিয়ামকগুলিতে স্থাপন করা যেতে পারে।
ENV ['RESCUE_404'] এর সাথে যদি আমি কোনও ব্যবহার করছি, তাই আমি বিচ্ছিন্নভাবে এআর :: রেকর্ডনটফাউন্ডের উত্থাপন পরীক্ষা করতে পারি। পরীক্ষাগুলিতে, আমি এই ENV ভারটিকে মিথ্যাতে সেট করতে পারি এবং আমার উদ্ধার_ক্রমে আগুন লাগবে না। এইভাবে আমি উত্থাপনকে শর্তযুক্ত 404 যুক্তি থেকে পৃথক করতে পারি।
class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, with: :conditional_404_redirect if ENV['RESCUE_404']
private
def conditional_404_redirect
track_404(@current_user)
if @current_user.present?
redirect_to_user_home
else
redirect_to_front
end
end
end