In part 3 we filled our database with a dozen of Ruby on Rails books with details taken from Amazon Web Services (AWS). We also fetched the book image and stored it into our own servers. In this part, we'll go back to AWS and fetch the book sales.
Book Sale Model
We need a model to store the sales rank we fetch from Amazon, so let's generate that now:
bundle exec rails generate model book_sale book:belongs_to sales_rank:integer
For each book we save the sales rank on the day we fetch it from Amazon. Let's do that next.
Amazon Proxy
In part 3 we created an AmazonProxy
class to communicate with AWS. We'll add a few methods to that class to get the sales rank information.
# app/models/amazon_proxy.rb
def self.import_sale(asin)
item = fetch(asin)
save_sale asin, item
end
private
def self.save_sale(asin, item)
book = Book.find_by(asin: asin)
existing = book.book_sales.where('DATE(created_at) = ?', Time.current.to_date).first
if existing.nil?
sales_rank = item.get('SalesRank')
book.book_sales.create(sales_rank: sales_rank)
book.update_sales_rank_movement
end
end
First we use our fetch
method we created on the previous post to grab the book details by the book's unique identifier (ASIN). Then (in the save_sale
method) we check that we don't have a ranking for the book on the same day. If we don't, we grab the SalesRank
item attribute from AWS and create a new sale record for the book in the data store. At the end, we update the sales movement of the book. For that we create an instance method on the Book
model:
def update_sales_rank_movement
recent_sales = sales.last(2)
return if recent_sales.size == 0
options = { previous_sales_rank: 0, last_sales_rank: recent_sales[0].sales_rank }
options[:previous_sales_rank] = recent_sales[1].sales_rank if recent_sales.size > 1
update options
end
This method is simple: we get the last two sales for the book and update the previous_sales_rank
and 'lastsalesrank' with the appropriate record. These two fields will then be used by the sales_rank_movement
method:
def sales_rank_movement
@sales_rank_movement ||= (last_sales_rank || 0) - (previous_sales_rank || 0)
end
As we see above, the movement shows the difference between the last sale and the one prior to that.
Rake
Next, let's create the Rake task that will populate our database everyday.
desc 'Import sales ranks'
task :sales => :environment do
Book.all.each do |book|
AmazonProxy.import_sale book.asin
end
end
No much mystery here, we navigate through the books and call the AmazonProxy
method to import the book's sale.
Conclusion
In this part of How to create a Rails app series, we imported the daily book sales from Amazon and updated our book records. This allows us to show the sales movements daily. In the next part, we'll build the page that shows the books and their sales ranking.
You can check out the previous posts in this series below:
Books on Rails live example.