Почему я получаю сообщение об ошибке ActionView :: Template :: Error (указано нулевое местоположение. Не удается создать URI) в Heroku, но не в разработке? - PullRequest
1 голос
/ 04 июля 2019

Я создаю простое приложение, которое использует API Open Weather Map и возвращает некоторые параметры погоды и рисунок, соответствующий текущей погоде.Пользователи могут искать текущую погоду города.

Локально все работает нормально, но я развернул в Heroku, и когда я ищу город, он выдает ошибку.Журналы Heroku показывают ActionView::Template::Error (Nil location provided. Can't build URI Мой код ниже.

В этой строке возникает ошибка: <div class="gif-container"><%= image_tag(find_gif_url, class: "gif") %>

views / current_weather.html.erb

<div class="page-wrapper">
  <h1 class="title">The weather in GIFs</h1>

  <div class="search">
    <%= form_tag(current_weather_forecasts_path, method: :get) do %>
      <%= text_field_tag :q, nil, placeholder: "Enter a city", class: "search-field" %>
      <%= button_tag type: 'submit', class: "search-button" do %>
        <i class="fas fa-search"></i>
      <% end %>
    <% end %>
  </div>

  <% if @forecasts_facade.invalid_city? %>
    <p>Please use a valid city name!</p>
  <% elsif @forecasts_facade.missing_city? %>
    <p>Please type in a city name!</p>
  <% elsif @forecasts_facade.forecast == {} %>
  <% else %>
    <p class="weather-description"><%= "#{@city.capitalize}: #{@forecasts_facade.description}" %></p>
    <div class="gif-container"><%= image_tag(find_gif_url, class: "gif") %>
      <span class="temperature weather-attribute"><%= "#{@forecasts_facade.temperature}°C" %></span>
      <span class="wind weather-attribute"><%= "wind:#{(@forecasts_facade.wind * 3.6).to_i}km/h" %></span> <!-- converts to km/hr -->
      <span class="humidity weather-attribute"><%= "humidity:#{@forecasts_facade.humidity}%" %></span>
    </div>
  <% end %>
</div>

reports_controller.rb

class ForecastsController < ApplicationController

  TOKEN = Rails.application.credentials.openweather_key

  def current_weather
    @city = params[:q]
    if @city.nil?
      @forecast = {}
    else
      @forecast = OpenWeatherApi.new(@city, TOKEN).my_location_forecast
    end
    @forecasts_facade = ForecastsFacade.new(@forecast)
  end
end

помощники / прогнозы_helper.rb

module ForecastsHelper
  GIFS = {
    thunder:
      {codes: [200, 201, 202, 210, 211, 212, 221, 230, 231, 232],
       urls: %w(
          https://media.giphy.com/media/26uf5HjasTtxtNCqQ/giphy.gif
          https://media.giphy.com/media/vS09bj1KrXwje/giphy.gif
)},
    light_rain:
      {codes: [300, 301, 302, 310, 311, 312, 313, 314, 321, 500, 501, 520, 521],
       urls: %w(
          https://media.giphy.com/media/xT9GEz2CeU9uaI2KZi/giphy.gif
          https://media.giphy.com/media/k28n1OPefBEeQ/giphy.gif
          https://media.giphy.com/media/H1eu9Vw957Rfi/giphy.gif
          https://media.giphy.com/media/Jyeo8wBpdwpry/giphy.gif
          https://media.giphy.com/media/14d8cRr25KPxbG/giphy.gif
)},
    heavy_rain:
      {codes: [502, 503, 504, 522, 531, 511],
       urls: %w(
          https://media.giphy.com/media/1Yfxps0AHRYBR2tK2G/giphy.gif
          https://media.giphy.com/media/7zSIC0roM238CVTS4u/giphy.gif
          https://media.giphy.com/media/l0Expn6D0D3g9NExq/giphy.gif
)},
    }

  def find_gif_url
    GIFS.each do |key, value|
      if value[:codes].include? @forecasts_facade.weather_code
        return value[:urls].sample
      end
    end
  end
end

фасады / прогнозы_facade.rb

class ForecastsFacade

  attr_accessor *%w(
    forecast
  ).freeze

  def initialize(forecast)
    @forecast = forecast
  end

  def temperature
    @temperature = forecast.dig('main', 'temp').to_i - 273
  end

  def weather_code
    @weather_code = forecast.dig('weather', 0, 'id').to_i
  end

  def description
    @description = forecast.dig('weather', 0, 'description')
  end

  def wind
    @wind = forecast.dig('wind', 'speed').to_i
  end

  def humidity
    @humidity = forecast.dig('main', 'humidity')
  end

  def invalid_city?
    forecast.dig('cod').to_i == 404 
  end

  def missing_city?
    forecast.dig('cod').to_i == 400
  end

end

услуги / open_weather_api.rb

class OpenWeatherApi
  include HTTParty
  base_uri "http://api.openweathermap.org"

  def initialize(city, appid)
    @options = { query: { q: city, APPID: appid } }
  end

  def my_location_forecast
    self.class.get("/data/2.5/weather", @options)
  end
end

1 Ответ

0 голосов
/ 04 июля 2019

Ваш звонок на этот метод:

def find_gif_url
  GIFS.each do |key, value|
    if value[:codes].include? @forecasts_facade.weather_code
      return value[:urls].sample
    end
  end
end

возвращается nil. То есть, ваш поиск записи в хеше GIFS фактически не дал результата. Рассмотрим значение @forecasts_facade.weather_code и почему его нельзя найти в значении value[:codes]. Добавление некоторого кода для обработки случая, когда запись в GIFS не была найдена, вероятно, является хорошей идеей.

Кроме того, я мог бы рекомендовать использовать Enumerable#find вместо итерации по GIFS и возврата вручную. Это будет «идиоматический Рубин» или «Рубиновый способ сделать это».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...