A simple Ruby on Rails application that provides weather forecast for a given address. It fetches current and extended forecast data using WeatherAPI, caches results per ZIP code, and displays the result in a TailwindCSS-styled UI.
- The user must provide an address that has a zip code.
- To aid the user in the address typing process, an auto-complete address feature was implemented via mapbox.
- When a user ends up typing or selecting an address that lacks a zip code, a fallback process can be triggered to get geocoordinates based on the address from a geo-location service. This would lack a zip code so that cache would not be set. Therefore, this was not implemented to avoid two types of simultaneous caching keys.
- If there is a zip code we can proceed with querying the forecast.
- An alternative cache key strategy can be rounding to 2 decimals geo-location coordinates, which does not affect the accuracy of the weather data returned back to the user. Affects by around ~1-10 kms.
- To facilitate user experience, forward geolocation can be used with an ambiguous address, to load possible addresses containing a zip code.
- The system is designed to support multiple weather APIs via an injectable client architecture.
- The
ForecastServiceis responsible for handling the cache and delegating to the correct API client. - Form objects handle input validation; decorators manage UI display logic.
- Weather data is cached per ZIP code for 30 minutes using
Rails.cache. - Stimulus is used to create a smooth, single-page address submission experience.
- Mock clients are injected in Cypress and test environments for speed and isolation.
- Add user authentication and favorites
- Support multi-language/localization for forecast terms
- Add background job to refresh cache asynchronously
- Handle more granular geocoding
- Support cache with geo-coordinates (rounded) when zip code is lacking.
/(root) renders the same content as in/forecasts/forecastswhere the user can submit the address/forecasts/:addressrenders the details of the address in the parameters
The following diagram illustrates the flow from the user interface to the weather API client and back to the view layer:
- Ruby 3.3.0
-
Clone the repository.
-
Run
bundle installto install dependencies. -
Run
bundle exec rails db:createto create the db. -
Make sure your rails master key is set (config/master.key)
-
Set your WeatherAPI and Mapbox keys inside the credentials file: 5.1 Run
EDITOR="code --wait" bundle exec rails credentials:edit. 5.2 Make sure it follows this structure:mapbox: public_token: <...> development: weather_api_key: <...> test: weather_api_key: "test_key" production: weather_api_key: <...> -
For development, the cache store is set to
:memory_store. In production, it uses:solid_cache_store.
NOTE: There are no db-backed models but rails will require the existence of the db.
bundle exec rails server`
Open your browser and type http://localhost:3000, you should see the "Weather Forecasts" initial page.
Run bundle exec rspec to execute the test suite. This includes system tests with capybara.
Code coverage reports are generated in
/coverage/index.htmlwhenCOVERAGE=trueis set when running specs.
There is an initial set of tests with Cypress. To run them interactively follow these steps:
- Run
yarn install. - Run
npx cypress open. - When the Cypress window opens choose E2E Testing.
- Choose any browser.
- Click Start E2E Testing...
- Click on any of the listed tests.
To simply run all Cypress tests run npx cypress run.
- Uses WeatherAPI for weather data
- Ruby on Rails 8.0.2
- Ruby 3.3.0
- HTTParty for HTTP requests
- Capybara + RSpec for testing
- Cypress for E2E browser tests
- Stimulus (via importmap-rails)


