I Ich denke, du meintest Show, denn der Index ist wirklich für Listen/Sammlungen. Und Sie sollten .first
auf dem wo, sonst haben Sie nur eine Beziehung, richtig? Verwenden Sie dann .first!
, um einen Fehler zu beheben, da Rails Rack-Middleware in Rails 4 public_exceptions behandelt wird, ist in einer grundlegenden Art und Weise, z.
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
Sie können auch @bar = Bar.find(params[:id])
, verwenden aber das ist veraltet und wird in Rails 4.1 entfernt werden, wonach Sie gem 'activerecord-deprecated_finders'
zu Ihrem Gemfile hätte hinzufügen zu verwenden.
Für den Index möchten Sie wahrscheinlich @bars = Bar.all
. Wenn Sie aus irgendeinem Grund filtern wollen und nicht wollen, etc., dann könnten Sie @bars = Bar.where(...).to_a
oder ähnliches verwenden.
Rails 4: Grund Exception Handling in Rack ist Automatische
Solange die Abfrage einen Fehler weg tritt, werden die Nachricht Teil des Fehlers für jedes unterstützte Format where to_(format)
können Rails 4 in der Lage sein sollte, zurückzukehren aufgerufen ein Hash (zB json, xml, etc.).
Um zu sehen, warum, werfen Sie einen Blick auf Rails Rack public_exceptions Middleware.
Wenn es HTML ist, wird es versuchen, in die entsprechende Datei aus dem öffentlichen Verzeichnis in Rails für den Statuscode einzulesen (z. B. 500.html
für einen Serverfehler/HTTP 500).
Wenn es ein anderes Format ist, wird es to_(the format)
auf dem Hash versuchen: { :status => status, :error => exception.message }
.Um zu sehen, wie dies funktioniert zu Rails gehen würde Konsole:
$ 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!\"}"
In der Middleware, werden Sie die X-Cascade
Header im Code und an verschiedenen Orten sehen im Zusammenhang mit Rails' Ausnahmebehandlung in der Zahnstange. Pro this answer wird die X-Cascade
-Kopfzeile auf pass
gesetzt, um Rack mitzuteilen, dass es andere Routen versuchen soll, um eine Ressource zu finden.
Rails 3.2.x: Kann Griff Ausnahmen in Rack-
In Rails 3.2.x, dass Code to_(format)
für die Antwort Körper zu tun, usw. ist nicht in public_exceptions.rb. Es handhabt nur HTML-Format.
Vielleicht könnten Sie versuchen, die alte Middleware mit der neueren Version durch einen Patch zu ersetzen.
Wenn Sie möchten, dass Rack Ihren Fehler auf eine spezifischere Weise behandelt, ohne einen Patch, siehe # 3 in José Valims Beitrag, "My five favorite “hidden” features in Rails 3.2".
In diesem und als another answer erwähnt, können Sie config.exceptions_app = self.routes
verwenden. Mit Routen, die auf einen benutzerdefinierten Controller verweisen, können Sie die Fehler von jedem Controller wie jede andere Anfrage behandeln. Beachten Sie das Bit über config.consider_all_requests_local = false
in Ihrem config/environments/development.rb
.
Sie müssen keine Routen verwenden, um exceptions_app
zu verwenden. Obwohl es ein wenig einschüchternd sein kann, ist es nur ein proc/lambda, das einen Hash nimmt und ein Array zurückgibt, dessen Format ist: [http_status_code_number, {headers hash...}, ['the response body']]
. Zum Beispiel sollten Sie in der Lage sein, diese Konfiguration in Ihrer Rails 3.2.x zu tun, um es Fehler wie Rails 4.0 behandeln zu lassen (dies ist die neueste public_exceptions Middleware kollabierte):
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
Hinweis: Für jedes Problem mit dieser Handhabung , die fehlersichere Implementierung ist in ActionDispatch::ShowExceptions
here.
Rails 3 und 4:
Wenn Sie eher Fehler Rendering in der Steuerung selbst haben möchten, können Sie tun einige Ausnahmen in Rails-Controller Handhabung:
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
Aber Sie brauchen nicht um Fehler zu melden. Sie könnten auch tun:
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
Sie auch rescue_from verwenden können, beispielsweise in Ihrem Controller oder Application, etc .:
rescue_from ActiveRecord::RecordNotFound, with: :not_found
def not_found(exception)
respond_to do |format|
format.json => { :error => e.message }, :status => 404
end
end
oder:
rescue_from ActiveRecord::RecordNotFound do |exception|
respond_to do |format|
format.json => { :error => e.message }, :status => 404
end
end
Obwohl einige häufige Fehler in der Steuerung verarbeitet werden kann, wenn Sie Fehler fehlende Routen im Zusammenhang usw. in json formatiert usw. müssen diese in Rack-Middleware behandelt werden.