I don't write code very much anymore. This has not necessarily been a conscious choice, it's more just how my career has evolved, and I find myself now managing developers, managing projects and products, or, as is currently the case, managing a small software company. With my recent acceptance into the Founder Institute however, I thought it was about time I spent a little time getting back on the tools. I'd always seen myself in the "technical founder" role, so I figured I better be able to back that up with actual skills.
Of the multitude of resources currently available online to level up my Ruby on Rails skills, I decided to give the curriculum over at RailsBridge a go. Now, I have worked with RoR a bit in the past however I figured if I was going to start somewhere, it really should be at the beginning with the Suggestotron
Having quickly whipped through the initial project, as most of the material was pretty familiar, I started on the Extra credit bits. And that's when I hit a little bit of a stumbling block. The second of these extra credit exercises is to:
Sort topics by their number of votes
That's pretty straight forward I thought, I can just order on a count() of the number of votes! But how do I do that?
I thought about adding
Comparable to the
Topic model class, but that felt like a bit of a hack, so I popped open a Google window and tried to figure out the Rails way of making this work. And that's when I came across
counter_cache, thanks to a very helpful post on StackOverflow.
The rest of this post will provide details on what I implemented. If you'd like to save time, jump straight on over to the post above and you should be on your way to ordered goodness!
Ordering the Topics
First up we need to add a column to the Topic table, so that Rails has somewhere to store the information.So, lets create a migration:
$ rails generate migration AddVotesCountToTopic votes_count:integer
Now, we want to make sure that the migration updates the current count of votes for all our current topics, and that it's initialised to zero for any new topics that are created. We're going to use the
migration_data gem to take care of updating the data for us, so the first thing we need to do it edit our Gemfile and add:
... and then let Bundler take care of installing it for us:
Now we can go ahead and edit our migration:
class AddVotesCountToTopic < ActiveRecord::Migration
add_column :topics, :votes_count, :integer, default: 0
Topic.all.each do |t|
t.votes_count = t.votes.size
Now run the migration:
Now that that's completed, we finally want to tell rails to use
class Vote < ActiveRecord::Base
belongs_to :topic, counter_cache: true
Finally, to order the Topics in the Suggestotron by the number of votes, we go into our Topics Controller and change the
index method so that it looks like:
@topics = Topic.all.order(votes_count: :desc)
And there we have it! All your Topics are belong to Order.
Disclaimer: I don't know if this really is the most "Rails-y" way of solving this problem - but it seemed simple and elegant to me. If you know of a better way, let me know in the comments below!