在本地生产环境把Rails4
切回 Rails3
的时候,一直报 500 错误
NoMethodError (undefined method `sweep' for #<Hash:0x007f2888ff0fe8>):
vendor/bundle/ruby/2.1.0/gems/actionpack-3.2.16/lib/action_dispatch/middleware/flash.rb:239:in `call'
vendor/bundle/ruby/2.1.0/gems/rack-1.4.5/lib/rack/session/abstract/id.rb:210:in `context'
vendor/bundle/ruby/2.1.0/gems/rack-1.4.5/lib/rack/session/abstract/id.rb:205:in `call'
vendor/bundle/ruby/2.1.0/gems/actionpack-3.2.16/lib/action_dispatch/middleware/cookies.rb:341:in `call'
vendor/bundle/ruby/2.1.0/gems/activerecord-3.2.16/lib/active_record/query_cache.rb:64:in `call'
vendor/bundle/ruby/2.1.0/gems/activerecord-3.2.16/lib/active_record/connection_adapters/abstract/connection_pool.rb:479:in `call'
vendor/bundle/ruby/2.1.0/gems/actionpack-3.2.16/lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.16/lib/active_support/callbacks.rb:405:in `_run__2392578677261619807__call__2174462519133804783__callbacks'
vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.16/lib/active_support/callbacks.rb:405:in `__run_callback'
vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.16/lib/active_support/callbacks.rb:385:in `_run_call_callbacks'
vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.16/lib/active_support/callbacks.rb:81:in `run_callbacks'
vendor/bundle/ruby/2.1.0/gems/actionpack-3.2.16/lib/action_dispatch/middleware/callbacks.rb:27:in `call'
vendor/bundle/ruby/2.1.0/gems/rack-1.4.5/lib/rack/sendfile.rb:102:in `call'
vendor/bundle/ruby/2.1.0/gems/actionpack-3.2.16/lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
vendor/bundle/ruby/2.1.0/gems/actionpack-3.2.16/lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
vendor/bundle/ruby/2.1.0/gems/actionpack-3.2.16/lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
vendor/bundle/ruby/2.1.0/gems/railties-3.2.16/lib/rails/rack/logger.rb:32:in `call_app'
vendor/bundle/ruby/2.1.0/gems/railties-3.2.16/lib/rails/rack/logger.rb:16:in `block in call'
vendor/bundle/ruby/2.1.0/gems/activesupport-3.2.16/lib/active_support/tagged_logging.rb:22:in `tagged'
vendor/bundle/ruby/2.1.0/gems/railties-3.2.16/lib/rails/rack/logger.rb:16:in `call'
vendor/bundle/ruby/2.1.0/gems/actionpack-3.2.16/lib/action_dispatch/middleware/request_id.rb:22:in `call'
vendor/bundle/ruby/2.1.0/gems/rack-1.4.5/lib/rack/methodoverride.rb:21:in `call'
vendor/bundle/ruby/2.1.0/gems/rack-1.4.5/lib/rack/runtime.rb:17:in `call'
vendor/bundle/ruby/2.1.0/gems/rack-1.4.5/lib/rack/lock.rb:15:in `call'
vendor/bundle/ruby/2.1.0/gems/rack-cache-1.2/lib/rack/cache/context.rb:136:in `forward'
vendor/bundle/ruby/2.1.0/gems/rack-cache-1.2/lib/rack/cache/context.rb:245:in `fetch'
vendor/bundle/ruby/2.1.0/gems/rack-cache-1.2/lib/rack/cache/context.rb:185:in `lookup'
vendor/bundle/ruby/2.1.0/gems/rack-cache-1.2/lib/rack/cache/context.rb:66:in `call!'
vendor/bundle/ruby/2.1.0/gems/rack-cache-1.2/lib/rack/cache/context.rb:51:in `call'
vendor/bundle/ruby/2.1.0/gems/rack-utf8_sanitizer-1.3.0/lib/rack/utf8_sanitizer.rb:15:in `call'
vendor/bundle/ruby/2.1.0/gems/railties-3.2.16/lib/rails/engine.rb:484:in `call'
vendor/bundle/ruby/2.1.0/gems/railties-3.2.16/lib/rails/application.rb:231:in `call'
vendor/bundle/ruby/2.1.0/gems/railties-3.2.16/lib/rails/railtie/configurable.rb:30:in `method_missing'
vendor/bundle/ruby/2.1.0/gems/rack-1.4.5/lib/rack/builder.rb:134:in `call'
vendor/bundle/ruby/2.1.0/gems/rack-1.4.5/lib/rack/urlmap.rb:64:in `block in call'
vendor/bundle/ruby/2.1.0/gems/rack-1.4.5/lib/rack/urlmap.rb:49:in `each'
vendor/bundle/ruby/2.1.0/gems/rack-1.4.5/lib/rack/urlmap.rb:49:in `call'
vendor/bundle/ruby/2.1.0/gems/unicorn-4.9.0/lib/unicorn/http_server.rb:580:in `process_client'
vendor/bundle/ruby/2.1.0/gems/unicorn-4.9.0/lib/unicorn/http_server.rb:674:in `worker_loop'
vendor/bundle/ruby/2.1.0/gems/unicorn-4.9.0/lib/unicorn/http_server.rb:529:in `spawn_missing_workers'
vendor/bundle/ruby/2.1.0/gems/unicorn-4.9.0/lib/unicorn/http_server.rb:140:in `start'
vendor/bundle/ruby/2.1.0/gems/unicorn-4.9.0/bin/unicorn:126:in `<top (required)>'
vendor/bundle/ruby/2.1.0/bin/unicorn:23:in `load'
vendor/bundle/ruby/2.1.0/bin/unicorn:23:in `<main>'
然后搜到这么一篇帖子
才发现原来是Rails4
把Flash
序列化到Cookies
不同于Rails3
,当Rails3
尝试去反序列化Cookies
中的Flash
的时候,就会报如上的错误。
解决方法是如果响应不了sweep
方法,那就把flash cookies
删除让程序重建即可。
新建文件 config/initializers/rails4_to_rails3_downgradability.rb
if Rails::VERSION::MAJOR == 3
module ActionDispatch
class Flash
def call(env)
if (session = env['rack.session']) && (flash = session['flash'])
# Beginning of change!
if flash.respond_to?(:sweep)
flash.sweep
else
session.delete("flash")
end
# End of change!
end
@app.call(env)
ensure
session = env['rack.session'] || {}
flash_hash = env[KEY]
if flash_hash
if !flash_hash.empty? || session.key?('flash')
session["flash"] = flash_hash
new_hash = flash_hash.dup
else
new_hash = flash_hash
end
env[KEY] = new_hash
end
if session.key?('flash') && session['flash'].empty?
session.delete('flash')
end
end
end
end
end
总结:要理解各个版本之间的各种差异,才能轻松应对。