ruby on rails - रेल में 404 पर रीडायरेक्ट कैसे करें?




ruby-on-rails http (6)

HTTP 404 स्थिति

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 और HTTP 404

यह भी याद रखें कि रेल कुछ ActiveRecord त्रुटियों को बचाता है, जैसे ActiveRecord::RecordNotFound 404 त्रुटि पृष्ठ प्रदर्शित करता है।

इसका मतलब है कि आपको इस कार्रवाई को खुद को बचाने की जरूरत नहीं है

def show
  user = User.find(params[:id])
end

User.find एक ActiveRecord::RecordNotFound User.find उठाता है जब उपयोगकर्ता मौजूद नहीं होता है। यह एक बहुत ही शक्तिशाली विशेषता है। निम्नलिखित कोड को देखो

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 पेज 'नकली' करना चाहता हूं। PHP में, मैं केवल त्रुटि कोड के साथ एक शीर्षलेख भेजूंगा जैसे:

header("HTTP/1.0 404 Not Found");

रेल के साथ ऐसा कैसे किया जाता है?


आप रेंडर फ़ाइल का भी उपयोग कर सकते हैं:

render file: "#{Rails.root}/public/404.html", layout: false, status: 404

जहां आप लेआउट का उपयोग करना चुन सकते हैं या नहीं।

एक और विकल्प इसे नियंत्रित करने के लिए अपवादों का उपयोग करना है:

raise ActiveRecord::RecordNotFound, "Record not found."

चयनित उत्तर रेल 3.1+ में काम नहीं करता है क्योंकि त्रुटि हैंडलर को मिडलवेयर में ले जाया गया था ( जिथब मुद्दा देखें)।

यहां वह समाधान है जो मैंने पाया जो मैं बहुत खुश हूं।

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 में। 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 और internal_error के लिए अलग-अलग विचार हैं।


त्रुटि प्रबंधन का परीक्षण करने के लिए, आप ऐसा कुछ कर सकते हैं:

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

ये आपकी मदद करेंगे ...

आवेदन नियंत्रक

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

स्टीवन सोरोक द्वारा प्रस्तुत नया चयनित उत्तर करीब है, लेकिन पूरा नहीं हुआ है। परीक्षण स्वयं इस तथ्य को छुपाता है कि यह सच 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

इस स्वस्थ परावर्तक ने मुझे सामग्री-प्रकार के विसंगति को स्थानांतरित करने की इजाजत दी जब सब कुछ peachy देखा :) मैं इन सभी तत्वों की जांच: आवंटित चर, प्रतिक्रिया कोड, प्रतिक्रिया सामग्री प्रकार, टेम्पलेट rendered, लेआउट rendered, फ़्लैश संदेश।

मैं उन अनुप्रयोगों पर सामग्री प्रकार की जांच छोड़ दूंगा जो कड़ाई से एचटीएमएल हैं ... कभी-कभी। आखिरकार, "एक संदेह सभी दराज जांचता है" :)

http://dilbert.com/strips/comic/1998-01-20/

एफवाईआई: मैं नियंत्रकों में होने वाली चीजों के लिए परीक्षण की सिफारिश नहीं करता, यानी "चाहिए_राइज"। आप किस चीज की परवाह करते हैं वह आउटपुट है। ऊपर दिए गए मेरे परीक्षणों ने मुझे विभिन्न समाधानों का प्रयास करने की अनुमति दी, और परीक्षण एक ही बना रहे हैं कि समाधान अपवाद, विशेष प्रतिपादन इत्यादि उठा रहा है या नहीं।





http-status-code-404