Skip to content

Instantly share code, notes, and snippets.

@dt1973
Last active August 29, 2015 14:22
Show Gist options
  • Save dt1973/b57d84bf39a75ea47e9b to your computer and use it in GitHub Desktop.
Save dt1973/b57d84bf39a75ea47e9b to your computer and use it in GitHub Desktop.

Trying to load some items from this external API in the background and save to database. When done, show them to the client using Ajax.

Live app which you can run on the fly: http://runnable.com/VXIdQ6KuRrYPdhKs/rest-client-ajax (remember to run bin/delayed_job start before hitting the big green Run button)

config/routes.rb

get '/check_items_loaded', to: 'main#check_items_loaded', as: :check_items_loaded

app/controllers/main_controller.rb

class MainController < ApplicationController
  def index
    # Delay fetching
    @products = Affiliate.delay.fetch
  end
  
  def check_items_loaded
    @items_status = Affiliate.where(url: params[:url]).exists?
    # respond_to :js
    render json: {items_status: @items_status}
  end
end

app/models/affiliate.rb

require "rest_client"

class Affiliate < ActiveRecord::Base
  def self.fetch
    response = RestClient::Request.execute(
      :method => :get,
      :url => "http://api.shopstyle.com/api/v2/products?pid=uid7849-6112293-28&fts=women&offset=0&limit=10"
    )

    @products = JSON.parse(response)["products"].map do |product|
      product = OpenStruct.new(product)
      affiliate = Affiliate.find_or_create_by(:name => product.name, :url => product.url)
      affiliate.save
    end
  end
end

20150604213141_add_items_to_affiliates.rb

class AddItemsToAffiliates < ActiveRecord::Migration
  def self.up
    change_table(:affiliates) do |t|
      t.string :name
      t.string :url
      t.datetime :updated_at
    end
  end
end

application.js

$.restClient = {
  poll: function() {
    console.log('Ran `poll`');

    setTimeout(this.request, 5000);
  },
  request: function() {
    console.log('Ran `request`');

    $.ajax({
      url: "/check_items_loaded",
      type: "GET",
      success: function(data){
      
        // Check for JSON MIME type which should automatically be converted to a JS object
      
        if(data.items_status) {
          console.log('Items now ready');
          $.restClient.addItems();
        } else {
          console.log('WAIT!! Items not ready ');
          
          // Start again

          $.restClient.poll();
        }
      },
      error: function() {
        console.log('Uh oh something else happened..');
      }
    });
  },
  addItems: function() {
    console.log('Ran `addItems`');

    var dataUrl = '/';

    $.get(dataUrl, function(html) {
      $(html).find('.product').appendTo($('body'));
      console.log(html);
    });

    console.log('New items were added');
  }
};

$(document).ready(function() {
  $.restClient.poll();
});

index.html.erb

<h1>Products from affiliate API</h1>
<% if @items_status %>
  <div class="products">
  
    <!-- If API changes products, new products will be added to our DB, so make sure we only display 10 at a time -->
  
    <% @products.last(10).each do |product| %>
      <div class="product">
        <%= link_to product.name, product.url %>
      </div>
    <% end %>
  </div>
<% else %>
  <div class="products processing">
    <p>Currently fetching.. comma backa lata dawg</p>
    
    <!-- Fetch via Ajax later -->
    
  </div>
<% end %>

views/main/check_items_loaded.js.erb

<!-- alert("<%= @items_status %>"); -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment