NameError(未初始化的常量Savon :: Request)

时间:2012-11-21 04:42:30

标签: ruby-on-rails controller gem savon

我正在尝试使用这个Ruby包装器https://github.com/mattetti/Pvwatts,但我的控制器app / controllers / projects_controller.rb(相关摘录)存在问题

require 'rubygems'
require 'savon'

class ProjectsController < ApplicationController
    <snip>
    def annual_production
        <snip>
        client = Savon::Client.new("http://pvwatts.nrel.gov/PVWATTS.asmx?WSDL")
        production_data = Pvwatts.new("<key>").yearly_production(:locationId => @locationId, :dc_rating => @dc_rating, :tilt => @tilt, :azimuth => @azimuth, :derate => @derate, :cost => @cost, :array_type => @array_type)
        <snip>
        respond_to do |format|
            if @project.update_attributes(params[:project])
                format.js
                format.html
            else
                format.html { render :action => "update" }
                format.json { render :json => @project.errors, :status => :unprocessable_entity }
            end
        end
    end
end

class Pvwatts
    Savon::Request.log = false
    <snip>
    def yearly_production(opts={})
        <snip>
        client = Savon::Client.new("http://pvwatts.nrel.gov/PVWATTS.asmx?WSDL")
        <snip>
        req = prep_request(@locationId, @dc_rating, @tilt, @azimuth, @derate, @array_type, @cost)
        response = client.get_pvwatts{|soap| soap.input = "GetPVWATTS"; soap.body = req }
        <snip>
    end
end

这是触发SO​​AP请求的按钮的定义

<input type=button id='pvwatt_update_button_id' value="Update from PVWatts" class='pvwatt_update_button_class'>

单击该按钮时,我收到“500 Internal Server Error”

Started GET "/projects/annual_production?id=4&keys=8<key>&reference_state=California&reference_city=San+Francisco&locationId=23234&dc_rating=1&tilt=20&azimuth=180&derate=80&cost=0.1&array_type=0" for <server_ip_address> at Tue Nov 20 20:07:18 -0800 2012
Processing by ProjectsController#annual_production as */*
Parameters: {"array_type"=>"0", "azimuth"=>"180", "locationId"=>"23234", "dc_rating"=>"1", "reference_city"=>"San Francisco", "keys"=>"<key>", "id"=>"4", "derate"=>"80", "reference_state"=>"California", "cost"=>"0.1", "tilt"=>"20"}
Project Load (0.2ms)  SELECT "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT 1  [["id", "4"]]
Completed 500 Internal Server Error in 282ms

NameError (uninitialized constant Savon::Request):
app/controllers/projects_controller.rb:1697
app/controllers/projects_controller.rb:1628:in `annual_production'

Rendered /var/lib/gems/1.8/gems/actionpack-3.2.9/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.6ms)
Rendered /var/lib/gems/1.8/gems/actionpack-3.2.9/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.2ms)
Rendered /var/lib/gems/1.8/gems/actionpack-3.2.9/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (10.0ms)

任何人都知道我做错了什么?

这是我安装的宝石列表

root@sv-001:/home/user/myapp# gem list

*** LOCAL GEMS ***

actionmailer (3.2.9)
actionpack (3.2.9)
activemodel (3.2.9)
activerecord (3.2.9)
activeresource (3.2.9)
activesupport (3.2.9)
akami (1.2.0)
arel (3.0.2)
builder (3.0.4)
bundler (1.2.2, 1.2.1)
coffee-rails (3.2.2)
coffee-script (2.2.0)
coffee-script-source (1.4.0)
erubis (2.7.0)
execjs (1.4.0)
git (1.2.5)
gyoku (0.4.6)
hike (1.2.1)
httpi (1.1.1)
i18n (0.6.1)
jeweler (1.8.4)
journey (1.0.4)
jquery-rails (2.1.3)
json (1.7.5)
libv8 (3.3.10.4 x86-linux)
mail (2.4.4)
mime-types (1.19)
multi_json (1.3.7)
nokogiri (1.5.5)
nori (1.1.3)
polyglot (0.3.3)
rack (1.4.1)
rack-cache (1.2)
rack-ssl (1.3.2)
rack-test (0.6.2)
rails (3.2.9)
railties (3.2.9)
rake (10.0.2, 10.0.1)
rdoc (3.12)
sass (3.2.3)
sass-rails (3.2.5)
savon (1.2.0)
sprockets (2.2.1)
sqlite3 (1.3.6)
therubyracer (0.10.2)
thor (0.16.0)
tilt (1.3.3)
treetop (1.4.12)
tzinfo (0.3.35)
uglifier (1.3.0)
wasabi (2.5.1)

这是我的ruby和rails版本

root@sv-001:/home/user/myapp# gem -v
1.8.15
root@sv-001:/home/user/myapp# ruby -v
ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-linux]
root@sv-001:/home/user/myapp# rails -v
Rails 3.2.9
root@sv-001:/home/user/myapp# 

更新1

NoMethodError (undefined method `debug' for :logger:Symbol):
app/controllers/projects_controller.rb:1757:in `yearly_production'
app/controllers/projects_controller.rb:1638:in `annual_production'

更新2

NoMethodError (undefined method `get_pvwatts' for #<Savon::Client:0xb275c15c>):
app/controllers/projects_controller.rb:1737:in `yearly_production'
app/controllers/projects_controller.rb:1628:in `annual_production'

更新3

对我有用的代码如下:

Savon.configure do |c|
   c.log = false
   c.logger = Rails.logger
end

client = Savon::Client.new do
    wsdl.document = "http://pvwatts.nrel.gov/PVWATTS.asmx?WSDL"
end

response = client.request :wsdl, "get_pvwatts" do
  soap.body = req
end

rdata = response.to_hash

2 个答案:

答案 0 :(得分:2)

Savon的语法已经改变,因为它越过了1.x版本。你已经安装了最新版本。

我使用名为SoapUI的工具调查了相关的Web服务。我在开发SOAP客户端时强烈推荐它。您可以在编写实际源代码之前从工具中创建调用并在SOAP级别上进行修改。 对于这个给予(遗留?)webservice,你需要明确地设置SOAPAction。

我将所有这些都放在一个有效的Ruby脚本中。我没有使用WSDL。 Savon的WSDL支持不完整。作者正在研究改进版本。我'硬编码'命名空间和端点。

#!ruby

require 'savon'
require 'pp'

Savon.configure do |c|
  c.log = true
  c.pretty_print_xml = true
end

client = Savon::Client.new do
  # wsdl.document = "http://pvwatts.nrel.gov/PVWATTS.asmx?WSDL"
  wsdl.endpoint = "http://pvwatts.nrel.gov/PVWATTS.asmx"
  wsdl.namespace = "http://pvwatts.nrel.gov"
end

begin
  response  = client.request :pvw, "GetPVWATTS" do
    http.headers['SOAPAction'] = '"http://pvwatts.nrel.gov/GetPVWATTS"'
    soap.body = { 'pvw:key' => 'your_secret',
                  'pvw:latitude' => 43,
                  'pvw:longitude' => 280 }
  end
  pp response.to_hash
rescue Savon::SOAP::Fault => error
  print error
end

它在我的机器上没有返回有效结果,因为我缺少授权码。让我们知道这是否有助于您迈出下一步。

答案 1 :(得分:0)

那个图书馆已经很老了,看起来Savon在过去两年里发生了变化。现在,相关的类似乎被称为Savon::SOAP::Request,并且它不再具有log=方法。只是从眼睛看代码,我你可以简单地删除对Savon::Request的所有引用,你应该没事。