Created
July 25, 2016 01:01
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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