Active Merchant - 未初始化常量ActiveSupport::XmlMini_REXML::StringIO

4

我有activemerchant 1.16.0和rails 3.0.5。

我正在尝试使用active merchant构建基本代码,与PayPal的网关通信。

if credit_card.valid?
  # or gateway.purchase to do both authorize and capture
  response = gateway.authorize(1000, credit_card, :ip => "127.0.0.1")
  if response.success?
    gateway.capture(1000, response.authorization)
    puts "Purchase complete!"
  else
    puts "Error: #{response.message}"
  end
else
  puts "Error: credit card is not valid. #{credit_card.errors.full_messages.join('. ')}"
end

I get the following error:

/Library/Ruby/Gems/1.8/gems/activesupport-3.0.9/lib/active_support/xml_mini/rexml.rb:20:in `parse': uninitialized constant ActiveSupport::XmlMini_REXML::StringIO (NameError)

这个错误来自于 gateway.authorize() 调用。有什么问题导致的呢?谢谢。

一个解决方法的hack可能是在你的代码顶部放置 require "stringio",但你不应该需要这样做。 - Andrew Grimm
嘿,非常感谢您的答案。这对我有效,但为什么会发生这种情况?还有其他更好的解决方法吗?这是我正在使用的 gem 版本的问题吗?还有其他人遇到这个问题吗? - harsha
我不知道。我会为这个问题添加Ruby on Rails标签,看看是否有其他人能理解它。 - Andrew Grimm
还是没有回应!看看现在有没有更多的兴趣,因为有赏金了。 - Andrew Grimm
2个回答

1

Andrew Grimm在他对这个问题的原始评论中基本上说中了要点。缺少的require 'stringio'确实是问题所在。但这是Rails的一个错误,更具体地说是ActiveSupport 3.0.9(这似乎是错误的来源)。我们可以使用rails的git提交历史来跟踪它。

首先,我们需要检出rails并切换到v3.0.9标签。如果我们现在查看activesupport/lib/active_support/xml_mini/rexml.rb,我们会发现require 'stringio'不在那里。就其本身而言,这并不重要,但请耐心等待。现在我们可以切换到下一个标签(v3.0.10.rc1),我们会发现该文件没有更新(很可能这个版本的rails将有相同的问题)。接下来的标签是v3.1.0.beta1,注意这一次文件顶部有一个require 'stringio'

我们可以查看引入此更改的提交(这里,来自2011年1月19日)。提交消息如下:

修复了一个缺失的 require,在非 Rails 环境中使用 AS 时会出现问题

这表明只要您在 Rails 环境中,就不会出现此问题。因此,我猜测环境的某些因素导致了该问题的出现,可能与 OP 所说的他们正在使用 Rails 3.0.5 有关,但错误来自 activesupport-3.0.9。也许代码是从忘记从 :environment 继承的 rake 任务中调用的(没有更多信息很难说)。无论如何,在代码顶部放置 require 'stringio' 绝对是解决方法,直到您升级到 Rails 3.1(一旦发布)后,将不再需要该 require。


这个修复程序应该从3.1.x回溯到3.0.x吗?Aaron "tenderlove" Patterson在2011年的RubyKaigi上说,由于没有人负责特定的分支,有时会忘记回溯。 - Andrew Grimm
正如你所说,它应该被回溯到3.0.x分支。我想这只是被遗忘了或者没有人想过去做它。 - skorks

1
根据问题描述,当代码单独运行时无法工作,但是添加require "stringio"后可以正常工作。
我怀疑ActiveMerchant已经进行了单元测试,但由于单元测试代码的其他部分间接地requires stringio,因此该依赖关系未被检测到。
最近我发现的一件事是,require 'yaml'会带来stringio库作为副作用:
StringIO.new
# NameError: uninitialized constant StringIO
#   from (irb):1
require "yaml"
# => true
StringIO.new
# => #<StringIO:0x7fb7d48ce360>
RUBY_VERSION
# => "1.8.7"

很容易想象ActiveMerchant(或Rails的其他部分)需要yaml的单元测试。

然而,这只是猜测。我没有检查过,因为我不使用Rails。


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