I'm still learning more about Rails and I'm starting to play around with APIs, but I can't seem to figure out how to get an input from a form to the Model.
I want to take the User input (in the form of a zip code) and have it spit out the weather info at that user location.
Form on home.html.erb
<%= form_tag(root_path) do %>
<%= label_tag :zip, "ENTER YOUR ZIPCODE TO FIND YOUR WEATHER" %><br>
<%= text_field_tag :zip,'', placeholder: "e.g. 91765 " %>
<%= submit_tag "show me the weather!" %>
<% end %>
Controller pages_controller.rb
class PagesController < ApplicationController
def home
@weather_lookup = WeatherLookup.new(params[:zip])
end
end
Model weather_lookup.rb
class WeatherLookup
attr_accessor :temperature, :weather_condition, :city, :state, :zip
def initialize(zip)
self.zip = zip
zip = 91765 if zip.blank?
weather_hash = fetch_weather(zip)
weather_values(weather_hash)
end
def fetch_weather(zip)
p zip
HTTParty.get("http://api.wunderground.com/api/API-KEY-HERE/geolookup/conditions/q/#{zip}.json")
end
def weather_values(weather_hash)
self.temperature = weather_hash.parsed_response['current_observation']['temp_f']
self.weather_condition = weather_hash.parsed_response['current_observation']['weather']
self.city = weather_hash.parsed_response['location']['city']
self.state = weather_hash.parsed_response['location']['state']
end
end
I'm not exactly sure how to get the input from the form to the model. This is literally just to show the weather. I'm not trying to save anything in a database
The form helper defaults to "POST" if you don't provide a method. From the looks of your controller, "GET" is what you want. Here's some documentation to provide additional context. The updated form:
<%= form_tag(root_path, method: "get") do %>
<%= label_tag :zip, "ENTER YOUR ZIPCODE TO FIND YOUR WEATHER" %><br>
<%= text_field_tag :zip,'', placeholder: "e.g. 91765 " %>
<%= submit_tag "show me the weather!" %>
<% end %>
Next, if you try to instantiate your @weather_lookup
variable without params[:zip]
, Rails will throw an error. Adding a conditional to your controller will solve this:
class PagesController < ApplicationController
def home
if params[:zip]
@weather_lookup = WeatherLookup.new(params[:zip])
end
end
end
Be sure your routes are set up. Something defining root
should exist in routes.rb
. For example:
root "pages#home"
I believe you also have to parse the JSON into a hash inside your model. Adding that to the weather_values
method:
def weather_values(weather_json)
weather_hash = JSON.parse weather_json
self.temperature = weather_hash.parsed_response['current_observation']['temp_f']
self.weather_condition = weather_hash.parsed_response['current_observation']['weather']
self.city = weather_hash.parsed_response['location']['city']
self.state = weather_hash.parsed_response['location']['state']
end
Finally, be sure you're referencing @weather_lookup
somewhere in your view, else the data won't show. A simple, unformatted example:
<%= @weather_lookup %>
Assuming the logic works in your model, the JSON should render after you submit a ZIP code via the form. I don't have an API key else I would have tested this myself.