I pensa che tu volessi mostrare, dato che l'indice è davvero per liste/collezioni. E dovresti prendere .first
dove, altrimenti hai solo una relazione, giusto? Quindi, utilizza .first!
per generare un errore, poiché il middleware Rack di Rails in Rails 4 verrà gestito in modo basico, ad es.
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
È anche possibile utilizzare @bar = Bar.find(params[:id])
, ma che è deprecato e sarà rimosso in Rails 4.1, dopo di che si dovrà aggiungere al vostro gem 'activerecord-deprecated_finders'
Gemfile da usare.
Per l'indice, probabilmente si desidera @bars = Bar.all
. Se per qualche motivo si desidera filtrare e non si desidera l'ambito, ecc., È possibile utilizzare @bars = Bar.where(...).to_a
o simile.
Rails 4: Gestione delle eccezioni di base nel rack è automatico
Finché la query prende il via un errore, le rotaie 4 dovrebbe essere in grado di restituire la parte del messaggio di errore per qualsiasi formato supportato where to_(format)
può essere chiamato su un hash (es. json, xml, ecc.).
Per capire perché, dai un'occhiata a Rails Rack public_exceptions middleware.
Se è html, proverà a leggere il file correlato dalla directory pubblica in Rails per il codice di stato (ad esempio 500.html
per un errore del server/HTTP 500).
Se è un altro formato, proverà a eseguire to_(the format)
sull'hash: { :status => status, :error => exception.message }
.Per vedere come questo dovrebbe funzionare andare a Rails console:
$ 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!\"}"
Nel middleware, vedrete il X-Cascade
intestazione nel codice e in vari luoghi legati alla Rails' la gestione delle eccezioni in rack. Per this answer, l'intestazione X-Cascade
è impostata su pass
per indicare a Rack di provare altri percorsi per trovare una risorsa.
Rails 3.2.x: può gestire le eccezioni in rack
In Rails 3.2.x, che il codice per fare to_(format)
per il corpo di risposta, ecc non è in public_exceptions.rb. Gestisce solo il formato html.
Forse potresti provare a sostituire il vecchio middleware con la versione più recente tramite una patch.
Se preferisci che Rack gestisca il tuo errore in modo più specifico senza patch, vedi # 3 nel post di José Valim, "My five favorite “hidden” features in Rails 3.2".
In questo e come dice anche another answer, è possibile utilizzare config.exceptions_app = self.routes
. Quindi con percorsi che puntano a un controller personalizzato, puoi gestire gli errori da qualsiasi controller come qualsiasi altra richiesta. Nota il bit su config.consider_all_requests_local = false
nel tuo config/environments/development.rb
.
Non è necessario utilizzare i percorsi per utilizzare exceptions_app
. Anche se può essere un po 'intimidatorio, è solo un proc/lambda che accetta un hash e restituisce un array il cui formato è: [http_status_code_number, {headers hash...}, ['the response body']]
. Per esempio, si dovrebbe essere in grado di fare questo nel vostro Rails 3.2.x di configurazione per rendere più gestire gli errori come Rails 4.0 (questo è l'ultimo public_exceptions middleware crollato):
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
Nota: Per qualsiasi problema di che la gestione , l'implementazione failsafe è in ActionDispatch::ShowExceptions
here.
Rails 3 e 4: Gestione delle eccezioni in Rails controller
Se si preferisce avere il rendering di errore nel controller stesso, si può fare:
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
Ma, non avete bisogno per aumentare gli errori. Si potrebbe anche fare:
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
È inoltre possibile utilizzare rescue_from, per esempio nel controller, o ApplicationController, ecc .:
rescue_from ActiveRecord::RecordNotFound, with: :not_found
def not_found(exception)
respond_to do |format|
format.json => { :error => e.message }, :status => 404
end
end
o:
rescue_from ActiveRecord::RecordNotFound do |exception|
respond_to do |format|
format.json => { :error => e.message }, :status => 404
end
end
Anche se alcuni errori comuni possono essere gestiti nel controllore, se gli errori relativi alle rotte mancanti, ecc formattato in JSON , ecc., quelli che devono essere gestiti nel middleware Rack.