Rails - "can't convert Symbol into String" 在生产环境中出现,仅限于生产环境。

4

我有一个局部视图,用于显示特定模型的flash消息。该局部视图如下:

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 %>

myModelFlash 方法只是简单地使用一个简单的正则表达式来获取键并检查特定前缀。它位于app/helpers/mymodelhelper.rb文件中。

module MyModelHelper
  def myModelFlash( key )
    m = /^_mymodel_(.*)/.match(key)
    m[1] unless m.nil?
  end
end

在我的开发和测试环境中,这个功能完美地运行。但是一旦部署到Heroku上,就会出现一个错误(ActionView::Template::Error),指向对match的调用,错误信息为"无法将符号转换为字符串"。
如果我从视图中删除对myModelFlash的调用,并仅显示键和值,那么它在不出错的情况下可以正常工作,因此至少键和值已经成功地传递到了部分视图中。由于某种原因,辅助方法认为传递给它的键是一个符号而不是字符串。
有任何想法可能是发生了什么?
1个回答

3

我建议你只需使用key.to_s作为一种快速解决方法。

你遇到问题的原因可能是测试服务器和生产服务器之间某些组件的某个版本不同。如果你的测试通过,但生产环境崩溃了,那就是非常糟糕的情况。

你应该比较你正在使用的ruby版本和所有gem的版本。如果你使用' bundler ',那么' bundle list '会给出一个很好的摘要。

如果你发现所有版本都是相同的...那么,我们将寻找另一个原因。

更新

由于问题似乎不是由版本差异引起的,而是由flash中的意外数据引起的,在生产环境中显然可能与测试环境中不同。

我建议你稍微改变myModelFlash方法。

def myModelFlash( key )
  if m = /^_mymodel_(.*)/.match(key.to_s)
    return m[1]
  end
end

Flash可能包含不同的键,其中一些可能是符号或其他任何内容,因此您必须准备处理所有这些键。

使用.to_skey参数转换应该是一个安全的选择,但如果您确定始终将flash键(我指与此“_mymodel”问题相关的键)设置为字符串,则可以更改此方法的第一行:

def myModelFlash( key )
  if key.is_a?(String) && m = /^_mymodel_(.*)/.match(key.to_s)
    return m[1]
  end
end

在你的测试中,将一些其他键添加到你的闪存中,然后测试该操作如何处理它们。


我已经尝试在帮助方法中使用key.to_s,但生成的字符串为空并且匹配失败。我将在将键传递给帮助程序之前尝试to_s,并查看那里发生了什么。 - Bryan Marble
因此,您的闪存包含不同的数据。尝试在生产服务器上调试闪存内容,并在测试中使用此值。在这种情况下,问题可能与组件的版本无关。 - Arsen7
使用 model_key = myModelFlash(key.to_s) 可行,不过正如提到的那样,这是一个折中方案。稍后我会检查一下 Ruby/Gem 的版本,看能找到什么解决方法。 - Bryan Marble
1
我认为在.match(key.to_s)中使用.to_s会更好。被调用的函数应该“修整”属性,而不是调用者。为了调试问题...好的,这可能会很长,所以我会更新答案,当我们有更多的空间时。 - Arsen7
感谢 @Arsen7 提供的精彩更新。我想我从未考虑过关键值除了字符串或符号外,还可以是其他东西,并且假设在符号上的 to_s 会起作用。谢谢你纠正了这一点。 - Bryan Marble

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接