【问题标题】:Error when using HTTParty gem to consume API: undefined method `[]' for nil:NilClass使用 HTTParty gem 使用 API 时出错:nil:NilClass 的未定义方法“[]”
【发布时间】:2017-07-11 04:40:34
【问题描述】:

尝试在 Ruby on Rails 中使用 HTTParty 解析 JSON 时,我不断收到此错误:"undefined method `[]' for nil:NilClass"

我希望能够使用 API,但无法让任何东西工作。

URL 工作正常,返回 JSON 元素没有问题;由于某种奇怪的原因,我无法访问它们并展示它们。

我正在使用 Rails 5 和 Ruby 2.4。所有 API 密钥都是隐藏的,但可以正确输入到我的 Rails 应用程序中。

这是我的 lib 文件:

require 'httparty'

class Wunderground
  include HTTParty
  format :json

  base_uri 'api.wunderground.com'

  attr_accessor :temp, :location, :icon, :desc, :url, :feel_like

  def initialize(response)
    @temp = response['current_observation']['temp_f']
    @location = response['current_observation']['display_location']['full']
    @icon = response['current_observation']['icon_url']
    @desc = response['current_observation']['weather']
    @url = response['current_observation']['forecast_url']
    @feel_like = response['current_observation']['feelslike_f']
  end

  def self.get_weather(state, city)
    response = get("/api/#{ENV["wunderground_key"]}/conditions/q/#{state}/#{city}.json")
    if response.success?
      new(response)
    else
      raise response.response
    end
  end

end

我已将 我的 api 密钥 输入到我的 application.yml 文件中,如下所示:

wunderground_key: "YOUR_API_KEY"

我的控制器:

class HomeController < ApplicationController

  require 'Wunderground'

  def wunderground
    @weather = Wunderground.get_weather(params[:state], params[:city])
  end

  def index
  end
end

我的路线:

  root 'home#index'

  get 'wunderground', to: 'home#wunderground'

我的看法:

<div>
    <%= form_tag wunderground_path, method: "get", class: "form-inline" do %>
    <%= text_field_tag :city, nil, class: "form-control", placeholder: "City Name" %>
    <%= select_tag :state, options_for_select(@states), :prompt => "Please select", class: "form-control" %>
    <%= submit_tag "Check Weather", name: nil, class: "btn btn-primary" %>
    <% end %>
</div>

<div>
<% if @weather.present? %>
  <h3><%= @weather.location %></h3>

  <p>The temperature is:
    <%= @weather.temp %></p>
  <p>Feels like:
    <%= @weather.feel_like %></p>

  <p>
    <%= @weather.desc %>
    <%= image_tag @weather.icon %>
  </p>
  <p>
    <%=link_to "Full Forecast", @weather.url, target: "_blank" %>
  </p>
</div>

<% end %>

编辑:

这是我在开发日志中看到的错误:

NoMethodError (undefined method `[]' for nil:NilClass):
lib/Wunderground.rb:12:in `initialize'
lib/Wunderground.rb:23:in `new'
lib/Wunderground.rb:23:in `get_weather'
app/controllers/home_controller.rb:6:in `wunderground'

【问题讨论】:

  • get_weather 方法中发布完整的错误日志和response 变量中的值。
  • 已编辑以反映开发日志中显示的完整错误。 “响应”是 Wunderground API 在访问 API 时返回的内容。
  • 我认为responseresponse['current_observation']nil。这就是您收到此错误的原因。如果你发布response变量的值,很容易找到原因。

标签: ruby-on-rails json ruby-on-rails-5 httparty


【解决方案1】:

错误来源

您收到此错误,因为 response['current_observation'] 为零。

调试策略

为了得出这个结论,我们通常会查看错误消息以及错误源自的代码行。

根据您的问题,很明显您已经知道错误是什么:undefined method '[]' for nil:NilClass,如果您查看堆栈跟踪,您的错误来自lib/Wunderground.rb:12:in initialize'

相关的代码行是这样的:

@temp = response['current_observation']['temp_f']

在 Ruby 中,object['foo'] 是“在 object 上调用 [] 方法并带有参数 'foo' 的语法糖。它也可以描述为“将 [] 消息发送到 object 并带有论据'foo'

链式[][] 调用只是在返回的对象上调用相同的方法。

实际上,您在 response 上使用 'current_observation' 调用 [],然后在使用 'temp_f' 的返回对象上调用 []。这意味着,您在 2 个对象上调用 []

  1. response
  2. response['current_observation'] 返回的对象

查看错误,undefined method '[]' for nil:NilClass,告诉我们上述两个对象之一是 nil。

由于在之前的调用中 response.success? 返回了 true,我们可以得出结论 response['current_observation'] 确实返回 nil。

进一步调试并找到解决此问题的方法

有几个选项。

  1. 漂亮地打印响应:pp response.parsed_response
  2. 使用 HTTParty 的 debug_output 设置查看 HTTP 请求响应日志。

    class Wunderground
      include HTTParty
      format :json
      debug_output $stdout
    
      # ...
      # rest of the code
      # ...
    end
    

启用调试模式后,查看服务器日志,以便了解 API 返回的响应。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多