インデックスは実際にはリスト/コレクション用であるため、ショーを意味していたと思います。そして、あなたは.first
どこにでも乗るべきです、さもなければあなたは関係を持っているだけですよね?次に、エラーを発生させるために使用します。これは、Rails 4 public_exceptions.first!
の Rails の Rack ミドルウェアが基本的な方法で処理するためです。
def show
# need to do to_s on params value if affected by security issue CVE-2013-1854
@bar = Bar.where(:foo_id => params[:id].to_s).first!
end
も使用できます@bar = Bar.find(params[:id])
が、これは推奨されておらず、Rails 4.1 で削除されgem 'activerecord-deprecated_finders'
ます。その後、Gemfile に追加して使用する必要があります。
インデックスについては、おそらく@bars = Bar.all
. 何らかの理由でフィルタリングしたいがスコープを設定したくない場合などは、@bars = Bar.where(...).to_a
または類似のものを使用できます。
Rails 4: ラックでの基本的な例外処理は自動です
クエリがエラーを開始する限り、Rails 4 はサポートされている形式のエラーのメッセージ部分を返すことができるはずですwhere to_(format)
(例: json、xml など)。
その理由を確認するには、Rails の Rack public_exceptionsミドルウェアを見てください。
500.html
html の場合、Rails の public ディレクトリから関連ファイルを読み取って、ステータス コード (サーバー エラー/HTTP 500 など) を取得しようとします。
他の形式の場合はto_(the format)
、ハッシュで実行しようとします: { :status => status, :error => exception.message }
. これがどのように機能するかを確認するには、Rails のコンソールに移動します。
$ rails c
...
1.9.3p392 :001 > {status: 500, error: "herro shraggy!"}.to_xml
=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<hash>\n <status type=\"integer\">500</status>\n <error>herro shraggy!</error>\n</hash>\n"
1.9.3p392 :002 > {status: 500, error: "herro shraggy!"}.to_json
=> "{\"status\":500,\"error\":\"herro shraggy!\"}"
ミドルウェアではX-Cascade
、コード内のヘッダーと、Rack での Rails の例外処理に関連するさまざまな場所にヘッダーが表示されます。この回答 に従って、X-Cascade
ヘッダーは、Rack にリソースを見つけるために他のルートを試すように指示するように設定されてpass
います。
Rails 3.2.x: Rack で例外を処理できる
Rails 3.2.xto_(format)
では、レスポンスボディなどに行うコードはpublic_exceptions.rbにありません。html 形式のみを処理します。
おそらく、パッチを介して古いミドルウェアを新しいバージョンに置き換えることができます。
パッチを適用せずに、より具体的な方法でエラーを Rack に処理させたい場合は、José Valim の投稿の #3 を参照してください。
その中で、別の回答でも言及されているように、を使用できますconfig.exceptions_app = self.routes
。次に、カスタム コントローラーを指すルートを使用して、他の要求と同様に、任意のコントローラーからのエラーを処理できます。の aboutconfig.consider_all_requests_local = false
に注意してくださいconfig/environments/development.rb
。
を使用するためにルートを使用する必要はありませんexceptions_app
。少し威圧的かもしれませんが、ハッシュを受け取り、形式が[http_status_code_number, {headers hash...}, ['the response body']]
. たとえば、Rails 3.2.x 構成でこれを実行して、Rails 4.0 のようなエラーを処理できるようにする必要があります (これは最新の public_exceptions ミドルウェアが折りたたまれています)。
config.exceptions_app = lambda do |env|
exception = env["action_dispatch.exception"]
status = env["PATH_INFO"][1..-1]
request = ActionDispatch::Request.new(env)
content_type = request.formats.first
body = { :status => status, :error => exception.message }
format = content_type && "to_#{content_type.to_sym}"
if format && body.respond_to?(format)
formatted_body = body.public_send(format)
[status, {'Content-Type' => "#{content_type}; charset=#{ActionDispatch::Response.default_charset}",
'Content-Length' => body.bytesize.to_s}, [formatted_body]]
else
found = false
path = "#{public_path}/#{status}.#{I18n.locale}.html" if I18n.locale
path = "#{public_path}/#{status}.html" unless path && (found = File.exist?(path))
if found || File.exist?(path)
[status, {'Content-Type' => "text/html; charset=#{ActionDispatch::Response.default_charset}",
'Content-Length' => body.bytesize.to_s}, [File.read(path)]]
else
[404, { "X-Cascade" => "pass" }, []]
end
end
end
注: その処理に関する問題については、フェイルセーフの実装がActionDispatch::ShowExceptions
ここにあります。
Rails 3 および 4: Rails コントローラーでいくつかの例外を処理する
コントローラー自体でレンダリング エラーを発生させたい場合は、次のようにします。
def show
respond_with @bar = Bar.where(:foo_id => params[:id].to_s).first!
rescue ActiveRecord::RecordNotFound => e
respond_to do |format|
format.json => { :error => e.message }, :status => 404
end
end
ただし、エラーを発生させる必要はありません。次のこともできます。
def show
@bar = Bar.where(:foo_id => params[:id].to_s).first
if @bar
respond_with @bar
else
respond_to do |format|
format.json => { :error => "Couldn't find Bar with id=#{params[:id]}" }, :status => 404
end
end
end
また、コントローラーや ApplicationController などで、rescue_fromを使用することもできます。
rescue_from ActiveRecord::RecordNotFound, with: :not_found
def not_found(exception)
respond_to do |format|
format.json => { :error => e.message }, :status => 404
end
end
また:
rescue_from ActiveRecord::RecordNotFound do |exception|
respond_to do |format|
format.json => { :error => e.message }, :status => 404
end
end
一部の一般的なエラーはコントローラーで処理できますが、ルートの欠落などに関連するエラーが json などでフォーマットされている場合は、Rack ミドルウェアで処理する必要があります。