Nota Originariamente era una domanda relativa agli errori 404, ma ora è una questione sul perché la patch che ho applicato avrebbe fatto la differenza.Qual è la differenza tra [X, Y, Z] .each {| m | includi m} e includi X, Y, Z?
Come si ottiene un'azione memorizzata nella cache per restituire un 404 su tutte le richieste che generano un'eccezione ActiveRecord :: RecordNotFound, non solo la prima richiesta?
Ad esempio, se si avvia un progetto di rotaie vuote, aggiungere un modello di prodotto e un controller, configurare il database.yml, configurare il backend di cache in production.rb, rake db: migrare, quindi avviare in produzione e premere il sito per un oggetto inesistente, ad es http://localhost:3000/product/show/1234
class ProductController < ApplicationController
caches_action :show
def show
@product = Product.find(params[:id])
render :text => "asdf"
end
end
La prima volta che la pagina viene colpito, si ritorna alla pagina 404 come previsto. Tuttavia, ogni colpo successivo a quell'URL restituisce una pagina vuota con 200 OK. Come si fa a restituire 404 ogni volta?
Qui ci sono le richieste CURL, seguito dal log
~ $ curl -I http://0.0.0.0:3000/product/show/1234
HTTP/1.1 404 Not Found
Connection: close
Date: Mon, 20 Apr 2009 22:49:18 GMT
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Content-Length: 14097
~ $ curl -I http://0.0.0.0:3000/product/show/1234
HTTP/1.1 200 OK
Connection: close
Date: Mon, 20 Apr 2009 22:49:19 GMT
X-Runtime: 6
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Content-Length: 0
La seconda risposta è chiaramente sbagliata.
Ecco una copia del registro per i 2 richieste:
Processing ProductController#show (for 127.0.0.1 at 2009-04-20 17:35:24) [GET]
Parameters: {"id"=>"1234"}
ActiveRecord::RecordNotFound (Couldn't find Product with ID=1234):
app/controllers/product_controller.rb:6:in `show'
Rendering rescues/layout (not_found)
Processing ProductController#show (for 127.0.0.1 at 2009-04-20 17:35:30) [GET]
Parameters: {"id"=>"1234"}
Filter chain halted as [#<ActionController::Caching::Actions::ActionCacheFilter:0x23e36d4 @options={:cache_path=>nil, :store_options=>{}, :layout=>nil}>] rendered_or_redirected.
Filter chain halted as [#<ActionController::Filters::AroundFilter:0x23e3580 @kind=:filter, @options={:unless=>nil, :if=>nil, :only=>#<Set: {"show"}>}, @method=#<ActionController::Caching::Actions::ActionCacheFilter:0x23e36d4 @options={:cache_path=>nil, :store_options=>{}, :layout=>nil}>, @identifier=nil>] did_not_yield.
Completed in 12ms (View: 0, DB: 0) | 200 OK [http://0.0.0.0/product/show/1234]
In effetti, se si tira l'azione nella cache dalla cache, si ha una sorta di immondizia vuoto in là.
cache.fetch("views/0.0.0.0:3000/product/show/1234")
=> ["", nil, [], []]
Cosa sto facendo di sbagliato qui?
Modifica
ho confermato che Rails 2.1.2 e 2.2.2 non presentano questo comportamento, ma 2.3.2 fa. (cioè le versioni precedenti non memorizzano una risposta vuota nella cache e lanciano un 404 per le richieste successive)
Sto riscontrando problemi con i bordi Rails, perché il caricamento causa il seguente errore all'avvio del server: foobar/vendor/rails/ActiveSupport/lib/active_support/dependencies.rb: 440: in `load_missing_constant ': non inizializzata ActionController costante :: fail-safe (NameError)
ho testato contro l'attuale capo del 2 -3 ramo stabile, 375e8976e3, e anch'esso mostra questo comportamento.
Modifica # 2 ho cercato di rintracciare quando il cambiamento si è verificato nel codebase Rails per determinare se sia stato intenzionale. Sembra che this seemingly innocuous commit sia il punto in cui inizia il bug.
Ecco i dettagli della bisezione, dove 404 indica il comportamento desiderato, 200 è indesiderato.
2-3-stable branch 375e8976e3 - 200 b1c989f28d - 200 beca1f2e15 - 200 f1fff0a48 - 200 f1e20ce9a7 - 200 a5004573d8 - 200 2e1132fad8 - 200 - the difference seems to start at this commit c69d8c043f - 404 d961592886 - 404 276ec16007 - 404 0efec6452 - 404 13c6c3cfc5 - 404 fb2325e35 - 404 2-2 stable 3cb89257b4 - 404
Ecco una patch che inverte il cambiamento, che, applicato al tag v2.3.2.1, cioè dc88847e5ce392eed210b97525c14fca55852867, risolve il problema. Io, tuttavia, non sono abbastanza intelligente da capire perché questo cambiamento apparentemente piccolo farebbe davvero la differenza! Forse qualcuno più intelligente di me potrebbe far luce sulla situazione?
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 0facf70..0790807 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -1403,12 +1403,9 @@ module ActionController #:nodoc:
end
Base.class_eval do
- [ Filters, Layout, Benchmarking, Rescue, Flash, MimeResponds, Helpers,
- Cookies, Caching, Verification, Streaming, SessionManagement,
- HttpAuthentication::Basic::ControllerMethods, HttpAuthentication::Digest::ControllerMethods,
- RecordIdentifier, RequestForgeryProtection, Translation
- ].each do |mod|
- include mod
- end
+ include Filters, Layout, Benchmarking, Rescue, Flash, MimeResponds, Helpers
+ include Cookies, Caching, Verification, Streaming, SessionManagement
+ include HttpAuthentication::Basic::ControllerMethods, HttpAuthentication::Digest::ControllerMethods
+ include RecordIdentifier, RequestForgeryProtection, Translation
end
end
Modifica # 3 La patch sembra risolvere anche il relativo bug, in mostra al di sopra, dove la "completata nel XYms (DB: Z) | 404 Not Found [http://0.0.0.0/product/1234]" non ha mostrato in il ceppo.
Modifica # 4 È possibile che questo cerotto interruppe l'altro in ActionPack, così ho approfondito e ha generato una correzione per il problema che non causa danni collaterali. La patch e gli aggiornamenti successivi saranno a the rails lighthouse
in effetti, sembra ragionevole. Grazie per la tua ricerca e intuizione! –