Rails アプリで通常の HTML フロントエンドと JSON API を使用しています。これで、誰かが呼び出す/api/not_existent_method.json
と、デフォルトの HTML 404 ページが返されます。{"error": "not_found"}
HTMLフロントエンドの元の404ページをそのまま残しながら、これを次のように変更する方法はありますか?
4 に答える
ある友人が、404 エラーだけでなく 500 エラーも処理するエレガントなソリューションを教えてくれました。実際、すべてのエラーを処理します。重要なのは、すべてのエラーが例外を生成し、それがいずれかによって処理されるまで、ラック ミドルウェアのスタックを介して上方に伝播することです。さらに詳しく知りたい場合は、この優れたスクリーンキャストをご覧ください。Rails には例外用の独自のハンドラーがありますが、あまり文書化されていないexceptions_app
構成オプションでオーバーライドできます。これで、独自のミドルウェアを作成するか、次のようにエラーをレールに戻すことができます。
# In your config/application.rb
config.exceptions_app = self.routes
次に、次のルートでこれらのルートを一致させる必要がありますconfig/routes.rb
。
get "/404" => "errors#not_found"
get "/500" => "errors#exception"
そして、これを処理するためのコントローラーを作成するだけです。
class ErrorsController < ActionController::Base
def not_found
if env["REQUEST_PATH"] =~ /^\/api/
render :json => {:error => "not-found"}.to_json, :status => 404
else
render :text => "404 Not found", :status => 404 # You can render your own template here
end
end
def exception
if env["REQUEST_PATH"] =~ /^\/api/
render :json => {:error => "internal-server-error"}.to_json, :status => 500
else
render :text => "500 Internal Server Error", :status => 500 # You can render your own template here
end
end
end
最後にもう 1 つ付け加えておきます。開発環境では、Rails は通常、404 または 500 ページをレンダリングせず、代わりにバックトレースを出力します。開発モードでの動作を確認したい場合は、ファイルErrorsController
のバックトレースを無効にしてください。config/enviroments/development.rb
config.consider_all_requests_local = false
確かに、次のようになります。
class ApplicationController < ActionController::Base
rescue_from NotFoundException, :with => :not_found
...
def not_found
respond_to do |format|
format.html { render :file => File.join(Rails.root, 'public', '404.html') }
format.json { render :text => '{"error": "not_found"}' }
end
end
end
NotFoundException
例外の実際の名前ではありません。Railsのバージョンと必要な動作によって異なります。Google検索で見つけるのはかなり簡単です。
あなたの最後に置くようにしてくださいroutes.rb
:
match '*foo', :format => true, :constraints => {:format => :json}, :to => lambda {|env| [404, {}, ['{"error": "not_found"}']] }