Skip to content

Instantly share code, notes, and snippets.

@brycedorn
Created July 25, 2016 01:01
Show Gist options
  • Save brycedorn/9bc549996c5696cc079ec3cb1c5df645 to your computer and use it in GitHub Desktop.
Save brycedorn/9bc549996c5696cc079ec3cb1c5df645 to your computer and use it in GitHub Desktop.
A Rails coding assignment that hits an external API and updates Product records based on a JSON payload.
require 'rubygems'
require 'sinatra'
require 'honeybadger'
require 'rest-client'
class App < Sinatra::Base
# Basic POST route to update Product records via a fetch
# to Omega Pricing's API
post '/update_records/' do
start_date = Date.today.prev_month.to_s
end_date = Date.today.to_s
product_records = get_product_records(start_date, end_date)
product_records.each do |product_record|
parse_external_product(product_record)
end
end
end
# Gets product records for a set amount of time
# @param [start_date] start of query interval
# @param [end_date] end of query interval
def get_product_records(start_date, end_date)
api_key = ENV['OMEGA_PRICING_KEY'] # 'abc123key'
api_url = ENV['OMEGA_PRICING_URL'] # 'https://omegapricinginc.com/pricing/records.json'
url = URI.escape(api_url)
api_params = {api_key: api_key, start_date: start_date, end_date: end_date} # Assuming the date format is "YYYY-MM-DD"
response = RestClient.get(url, {params: api_params})
if(response.status_code == 200)
JSON.parse(response.body)
else
raise "Error making GET request to Omega Pricing's API."
end
end
# Parses external Product records if conditions are met
# @param [external_product_record] json payload of product_record information
def parse_external_product(external_product_record)
existing_product = Product.where(external_product_id: external_product_record['id']).first
if existing_product.present?
update_product(existing_product.id, external_product_record)
elsif (discontinued = external_product_record['discontinued'])
return
elsif existing_product.empty? && !discontinued
Product.create!(external_product_record) # Assuming that the Product initializer allows an external_product_record as a param
else
raise "Error while parsing external product record: #{external_product_record}."
end
end
# Updates product price and creates a PastPriceRecord
# @param [product_id] ID for Product to be updated
# @param [external_product_record] json payload of product_record information
def update_product(product_id, external_product_record)
return unless (product = Product.find(product_id)).present? && (new_price = external_product_record['price']).present?
if product.name != external_product_record['name']
raise "Name mismatch for Product ##{product_id}: was expecting #{product.name} but got got #{external_product_record['name']}."
else
ActiveRecord::Base.transaction do
percentage_change = product.price / new_price # Assuming new_price is >= 0
product.update!({price: new_price})
product.past_price_records.build!(price: new_price, percentage_change: percentage_change) # Assuming this method exists; Rails convention
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment