Tracking page views really isn't too difficult with Ruby on Rails. Consider a blog with a
Post model, which has a
def increment(by = 1) self.views ||= 0 self.views += by self.save end
def show @post = … @post.increment … end
This is very simple, and it works. But it also means that for every request, we have to do an extra SQL query to update the post with the new view count. For a blog, we want to optimize for fast page loads, so it would be better to move this work into an asynchronously queue.
After you install Afterparty, change
posts_controller to increment asynchronously:
def show @post = … job = Afterparty::BasicJob.new @post, :increment Rails.configuration.queue << job … end
Afterparty::BasicJob will create a simple job that accepts an object, a method, and any number of arguments. When the job is run, the method will simply be called on the object. Make sure you have a worker queue running by executing
rake jobs:work. The next time you view that post, the
views value will increment in the background.
This absolutely has some trade-offs. For one, you don't display the exact count of views when a visitor views a post. This is because the value is being updated simultaneously as the page is rendered. You can account for this by displaying
@post.views + 1, but you still can't guarantee that it's accurate, as there may be other background jobs also about to increment the views of this post. The advantage of this approach is that page requests will be much faster. If you're in a situation like this where you want to count something and care about fast requests more than precise counts, I encourage you to try this pattern.