Skip to content

Cached External Content

JP Barbosa edited this page Jul 23, 2015 · 2 revisions

Cached External Content

Install Redis Gem
echo "gem 'redis-rails'" >> Gemfile
bundle install
Add Redis to config
nano config/application.rb
config.cache_store = :redis_store
Create weather model
nano app/models/weather.rb
class Weather

  def self.read
    Rails.cache.read('weather')
  end
  def self.write
    require 'open-uri'
    json = open('http://api.openweathermap.org/data/2.5/weather?q=Sao_Paulo,br&units=metric').read
    hash = JSON.parse json
    hash['datetime'] = Time.now.to_i
    Rails.cache.write('weather', hash)
    hash
  end
  def self.fetch
    if read
      if age > 60
        WeatherUpdateJob.perform_later
      end
      read
    else
      write
    end
  end
  def self.age
    if read
      (Time.now - Time.at(read['datetime']).to_datetime) / 1.minute
    end
  end
end
Create active job
rails g job weather_update
nano app/jobs/weather_update_job.rb
class WeatherUpdateJob < ActiveJob::Base
  queue_as :default
  def perform(*args)
    Weather.write
  end
end
Add routes and create controller
nano config/routes.rb
...
  get 'weather'        => 'weather#show'
  get 'weather/update' => 'weather#update'
...
nano app/controllers/weather_controller.rb
class WeatherController < ApplicationController
  def show
    render json: Weather.fetch
  end
  def update
    Weather.write
    redirect_to weather_url
  end
end
Replace JS with local URI and show when the data was cached
nano app/assets/javascripts/application.js
function weather() {
  $.getJSON("/weather", function(data) {
    var datetime = new Date(data.datetime*1000);
    $('#weather').html('Sao Paulo: ' + data.main.temp + ' Celsius - Last update: ' + datetime.toString());
  });
}
Create task to be executed from time-to-time using cron
nano lib/tasks/weather.rake
desc "This task is called using cron or Heroku scheduler add-on"
task :weather => :environment do
  Weather.write
  puts Weather.read
end
Restart Redis and Sidekiq with mailers and default
redis-server
sidekiq -q mailers -q default
Open Rails console and play with cache
spring stop
rails c
Weather.read
Weather.fetch
Weather.write
Weather.read
Weather.age
WeatherUpdateJob.perform_later
Restart Rails server
rails s
Open any page in the browser and check for weather info
open http://localhost:3000
Add cached external content to Git
git add .
git commit -m "Add cached external content"
Next step: Tests