I have partial view that displays model-specific flash messages. The partial looks like:
app/views/mymodel/_flashpartial.erb
<% flash.each do |key, value| %>
<% if model_key = myModelFlash(key) then %>
<%= content_tag(:div, value, :class => "flash #{model_key}") %>
<% end %>
<% end %>
The myModelFlash
method simply takes the key and checks for a particular prefix using a simple regex. It's located in
app/helpers/mymodelhelper.rb
module MyModelHelper
def myModelFlash( key )
m = /^_mymodel_(.*)/.match(key)
m[1] unless m.nil?
end
end
This works perfectly fine in my development and test environments. As soon as it goes onto Heroku, I get an error saying (ActionView::Template::Error) "can't convert Symbol into String" pointing to the call to match
.
If I remove the call to myModelFlash
from the view and simply display the key and value, that works just fine in terms of not erroring out, so at the very least the key and value are getting into the partial view just fine. For some reason the helper method thinks that the key being passed into it is a symbol and not a String.
Any ideas as to why this might be happening?
I suggest you just use key.to_s
as a quick workaround.
The reason for your problem may be that some version of some component differs between your testing server and the production server. If your tests pass, and your production environment crashes, that is a very bad situation.
You should compare the versions of ruby and all of the gems you are using. If you use 'bundler' then 'bundle list' gives a nice summary.
If you find out that all the versions are the same... Well, we will be looking for another reason.
Update
As it seems that the problem is caused not by the version differences, but by unexpected data in flash, which obviously in production environment may be different than in testing.
I suggest you change the myModelFlash
method a little.
def myModelFlash( key )
if m = /^_mymodel_(.*)/.match(key.to_s)
return m[1]
end
end
The flash may contain different keys, some of them may be Symbols or really anything, so you must be prepared to handle all of them.
Converting the key
parameter with .to_s
should be a safe choice, but if you are sure that you always set the flash keys (I mean the keys related to this "_mymodel" issue) as Strings, you may change the first line of this method:
def myModelFlash( key )
if key.is_a?(String) && m = /^_mymodel_(.*)/.match(key.to_s)
return m[1]
end
end
And in your test, add a few other keys to your flash, and then test how the action handles them.