我看到一些真正奇怪的行为与ActiveRecord有关,因为它与作业有关。我有一个名为 Venue 的ActiveRecord模型,其中包括Venue的测量值,所有整数都小于1K。我们通过XML Feed添加Venues。在模型本身上,我有一个Venue.from_xml_feed
方法获取XML,解析并创建场地。
问题来自测量。使用Nokogiri
,我可以像这样解析测量结果:
elems = xml.xpath("//*[@id]")
elems.each do |node|
distance = node.css("distances")
rs = distance.attr("rs")
// get the rest of the sides
# using new instead of create to print right_side, behavior is the same
venue = Venue.new right_side: rs # etc
venue.save
puts venue.right_side
end
问题在于venue.right_side
始终评估为nil
,即使distance.attr("rs")
包含合法值,例如400.所以此代码:
rs = distance.attr("rs")
puts rs
Venue.new right_side: rs
将打印400
,然后将rs保存为nil。如果我尝试任何类型的类型转换,如下所示:
content = distance.attr("rs").content
str = content.to_s
int = Integer(str)
puts "Is int and Integer? #{int.is_a? Integer}"
Venue.new right_side: int
它将打印Is int an Integer? true
,然后再次保存,将Venue.right_side
保存为nil
。
但是,如果我只是显式创建一个随机整数:
int = 400
Venue.new right_side: int
它会将Venue.right_side
保存为400
。任何人都可以告诉我这是怎么回事?
答案 0 :(得分:0)
好吧,你没有包含必备的示例XML来确认这一点,所以你得到了一个相当通用的答案。
在您使用的代码中:
distance = node.css("distances")
rs = distance.attr("rs")
css
不会返回您的想法。它返回一个NodeSet,类似于一个Array。当您尝试在NodeSet上使用attr
时,您将设置该值,而不是检索它。来自文档:
#attr(key, value = nil, &blk) ⇒ Object (also: #set, #attribute)
在NodeSet中的所有Node对象上将属性键设置为value或blk的返回值。
因为您没有使用值,所以最终的操作是从标记中删除属性,然后返回nil,Ruby将nil分配给rs
。
如果要获取节点的属性,则需要指向节点本身,因此请使用at
或at_css
,其中任何一个都返回节点。获得节点后,您可以使用attribute
检索该值,或使用与此未经测试的代码类似的[]
快捷方式:
rs = node.at('distances')['rs']
但是,由于您没有提供XML,因此无法确定您可能尝试做什么,或者此代码是否完全准确。