Rails 3.1 hash每个都给出TypeError

我有哈希(Hash.from_xml)看起来像这样(来自inspect):

{ "FileName"=>"hofplayers.xml", "Version"=>"1.0", "UserID"=>"3955847", "FetchedDate"=>"2011-08-16 00:41:02", "PlayerList"=>{ "Player"=>{ "PlayerId"=>"92121587", "FirstName"=>"Gennady", "NickName"=>nil, "LastName"=>"Buzykin", "Age"=>"45", "NextBirthday"=>"2011-09-24 22:10:00", "ArrivalDate"=>"2008-03-08 16:37:00", "ExpertType"=>"15", "HofDate"=>"2010-01-23 16:10:00", "HofAge"=>"40" } } } 

然后我正在迭代每个,因为可以有多个玩家:

    

并且它因TypeError而失败:无法将String转换为Integer 。 但是当有多个玩家时,它就像我想要的那样。 问题似乎是当有单个玩家各自制造数组而不是散列时,player.inspect给出:

  ["PlayerId", "92121587"] ["FirstName", "Gennady"] ["NickName", nil] ["LastName", "Buzykin"] ["Age", "45"] ["NextBirthday", "2011-09-24 22:10:00"] ["ArrivalDate", "2008-03-08 16:37:00"] ["ExpertType", "15"] ["HofDate", "2010-01-23 16:10:00"] ["HofAge", "40"] 

代替

  { "PlayerId"=>"25787535", "FirstName"=>"Rico", "NickName"=>nil, "LastName"=>"van Oostveen", "Age"=>"42", "NextBirthday"=>"2011-10-23 22:18:00", "ArrivalDate"=>"2006-02-11 18:43:00", "ExpertType"=>"2", "HofDate"=>"2010-04-25 22:01:00", "HofAge"=>"38" } 

那么我做错了什么?

当您在Hash上执行each时,您会获得一个键/值对列表,然后您尝试使用字符串索引这些对并为您提供错误。 你可以做多少来改变from_xmlfunction,但你可以解决它。

您可以在控制器中修补Hash:

 if(@hof['PlayerList']['Player'].is_a?(Hash)) @hof['PlayerList']['Player'] = [ @hof['PlayerList']['Player'] ] end # or if(!@hof['PlayerList']['Player'].is_a?(Array)) @hof['PlayerList']['Player'] = [ @hof['PlayerList']['Player'] ] end 

如果你没有你期望的东西,你只需要将它作为一个包含一个元素的数组; 你选择哪种测试取决于你期望从from_xml得到什么样的东西但是我倾向于“非数组”检查,因为那与你想要做的完全匹配。

或者您可以尝试在视图中对其进行排序:

 <% [ @hof['PlayerList']['Player'] ].flatten(1).each do |player| %> 

这基本上包装了你在数组中的任何东西,然后将它flatten(1)一层,如果你已经有一个数组,则需要flatten(1)调用。 如果你从一个数组开始,那么[ ].flatten(1)是一个无操作( flatten调用将撤消[]做什么)除了浪费一点CPU时间之外没有任何明显的效果; 如果你从一个哈希开始,那么[ ... ]将把它变成一个数组, flatten将不会做任何事情(但浪费一点CPU)。

我想到的一件事是:

 <% @hof['PlayerList']['Player'].each do |player| %> <%= player['NickName']%> <% end %> 

没有循环播放器。 它循环遍历’Player’哈希的名称/值对。 编辑。 通过这个我的意思是它将循环通过key1,value1,key2,value2,key3,…等。 循环的每次迭代一次……

我想你会想要这样的东西:

 <% @hof['PlayerList'].each_pair do |player, player_data| %> <%= player_data['NickName']%> <% end %>