Skip to content

Instantly share code, notes, and snippets.

@mixflame
Last active December 31, 2015 21:29
Show Gist options
  • Save mixflame/8047193 to your computer and use it in GitHub Desktop.
Save mixflame/8047193 to your computer and use it in GitHub Desktop.
Share flash between Rails 2 and Rails 4 with monkey patches! Works both ways with sweeping! If you actually have this problem, *facepalm*
# Rails 2.2.2.2
# vendor/bundle/ruby/1.8/gems/actionpack-2.2.2.2/lib/action_controller/flash.rb
# Access the contents of the flash. Use <tt>flash["notice"]</tt> to read a notice you put there or
# <tt>flash["notice"] = "hello"</tt> to put a new one.
# Note that if sessions are disabled only flash.now will work.
def flash(refresh = false) #:doc:
if !defined?(@_flash) || refresh
@_flash =
if session.is_a?(Hash)
# don't put flash in session if disabled
FlashHash.new
else
# otherwise, session is a CGI::Session or a TestSession
# so make sure it gets retrieved from/saved to session storage after request processing
session["flash"] ||= FlashHash.new # <-- will use Rails 4 hash if exists, but doesnt know it
# leaving these lines in as they orchestrated the patch
# Rails.logger.info "!!!! #{session["flash"].class}"
# Rails.logger.info "!!!! #{session["flash"].inspect}"
if session["flash"].class == Hash
# convert Rails 4 Hash to Rails 2 FlashHash
new_hash = FlashHash.new
session["flash"]["flashes"].each do |k, v|
new_hash[k] = v
end
session["flash"] = new_hash
end
session["flash"] # actually return the converted object
end
end
@_flash
end
# Rails 4.0.2
# vendor/bundle/ruby/1.9.1/gems/actionpack-4.0.2/lib/action_dispatch/middleware/flash.rb
# Rails 2 just uses a hash under session['flash'] whereas Rails 4 uses a more complicated structure
# after sweep, this comes back as an empty hash to Rails 4.. which then breaks flash completely
# only required thing to do is restore session['flash']['flashes'] .. discard can and will default to [] which is fine
# note: this doesn't end up using the Rails 3 code because.. well it's Rails 3 and Rails 2 used FlashHash internally
# but doesnt seem to serialize it into the session, fooling Rails 4 into thinking it's a Rails 4 style flash Hash
def flash
# Rails 2 stores Flashes different
session["flash"]["flashes"] ||= {}
# move Rails 2 flashes to Rails 4 flashes location
session["flash"].each do |k, v|
if k.class == Symbol # hopefully skip "flashes", "discard"
session["flash"]["flashes"][k] = v
session["flash"].delete(k)
end
end
@env[Flash::KEY] ||= Flash::FlashHash.from_session_value(session["flash"])
end
@mixflame
Copy link
Author

related errors:

undefined method `keys' for nil:NilClass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment