0

我正在尝试使用这个 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

这是触发 SOAP 请求的按钮的定义

<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
4

2 回答 2

2

Savon 的语法自从 1.x 版本以来发生了变化。您已安装最新版本。

我使用名为 SoapUI 的工具调查了有问题的 Web 服务。我在开发 SOAP 客户端时强烈推荐它。您可以在工具之外创建调用,并且可以在编写实际源代码之前在 SOAP 级别上进行修改。对于这个给予(遗留?)网络服务,您需要明确设置 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

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

于 2012-11-22T02:51:52.413 回答
0

那个图书馆挺旧的,看来这两年Savon变了。有问题的类现在似乎被调用了Savon::SOAP::Request,它不再有log=方法。仅仅通过观察代码,我认为你可以简单地删除所有引用Savon::Request,你应该没问题。

于 2012-11-21T19:06:23.810 回答