Rails 3.1散列每个给出TypeError [英] Rails 3.1 hash each gives TypeError

查看:112
本文介绍了Rails 3.1散列每个给出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=>无,
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







然后我将每个可以有多个玩家:

 <%@hof ['PlayerList'] ['Player']。 |球员| %GT; 
<%= player ['NickName']%>
<%end%>

它无法使用 TypeError:无法将字符串转换为整数。但是当有多个玩家时,它就像我想要的那样工作。问题似乎是,当单个玩家每个人都使用数组而不是散列时,player.inspect会给出:

  [PlayerId ,92121587] 
[FirstName,Gennady]
[NickName,nil]
[LastName,Buzykin]
[年龄,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
}

所以我做错了什么?

each
时,你会得到一个键/值对列表,然后你试着用一个字符串对这些对进行索引,这会给你错误。你可以做些什么来改变 from_xml ,但你可以解决它。



你可以修补Hash in your controller:

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

如果您没有满足自己的期望,它是一个元素的数组;你选择哪种测试取决于你期望从 from_xml 得到什么类型的东西,但是我会倾向于非数组检查,因为它完全符合你的重新尝试去做。



或者您可以尝试在您的视图中进行整理:

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

这基本上包含了你在数组中的所有内容,然后将它平坦化到一个级别, flatten(1) 如果您已经有数组,则需要调用。如果从一个数组开始,那么 [] .flatten(1)是一个无操作符( flatten 调用将会取消 [] 的作用),除了一点CPU浪费时间之外,它不会有任何明显的效果;如果你从一个散列开始,那么 [...] 会将它变成一个数组,并且 flatten 不会做任何事情(但浪费一点CPU)。


I have hash(Hash.from_xml) which looks like this (from 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"
        }
    }
}

Then I'm iterating with each as there can be more then one player:

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

And it fails with TypeError: can't convert String into Integer. But it works like I want when there is more than one player. The problem seems to be that when there is single player each makes arrays instead of hash, player.inspect gives:

 ["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"]

Instead of

 {
     "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"
 }

So what I'm doing wrong?

解决方案

When you do each on a Hash, you get a list of key/value pairs, then you try to index those pairs with a string and that gives you your error. There's not much you can do to change what from_xml does but you can work around it.

You could patch the Hash in your controller:

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

If you don't have what you're expecting, you'd just make it an array with one element; which test you choose depends on what sorts of things you're expecting to get from from_xml but I'd lean towards the "not array" check since that exactly matches what you're trying to do.

Or you could try sorting it out in your view:

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

That basically wraps whatever you have in an array and then flattens it one level, the flatten(1) call is needed in case you already have an array. If you start off with an array then the [ ].flatten(1) is a no-op (the flatten call will undo what [] does) that won't have any noticeable effect other than a bit of wasted CPU time; if you start with a hash, then [ ... ] will turn it into an array and flatten won't do anything (but waste a bit of CPU).

这篇关于Rails 3.1散列每个给出TypeError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆