REST Client, Delayed Job and Ajax
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 %>"); -->