What’s the difference between order and sort?

ActiveRecord does some amazing stuff (sometimes). It takes a relational database and then maps it to ruby objects – a task that’s not trivial, as object-orientated design doesn’t really map well to good database design.

But sometimes you need to be aware of what ActiveRecord is doing and where it’s doing it …

For example, if you have a list of people that you want to display on a page; showing the ones with the most recent updates first, you need to sort your list in some way.

Ruby collections offer the sort method – which seems like a good fit. You supply a block and then it uses that to figure out which order the results should be in …

The <=> operator compares two values and returns -1, 0 or 1 depending upon their sort order. So the sort method goes through each item in the list and compares it with other items until it’s put them in the right place (and, in true object-orientated fashion, it doesn’t reveal the algorithm it uses to do this).

Your view would then look something like this

This will do the job, but there are two problems with it.

Firstly, we’ve got all this logic in the view – making it hard to understand (I find views are the hardest of all code to read).

Secondly, is sort really the right choice here?

Let’s deal with the second point first.

This will work great if there are ten people in our database. ActiveRecord goes to the database, pulls out the data, creates a load of Person models for us and then we go through and sort them.

But what if there were a thousand people? Or a million? Do we really want to go to the database, pull out a million ActiveRecord models and then sort them in memory? Even worse, do we want to display a million records on the page – surely we’d want to paginate the results and show maybe the 100 most recently updated ones, with a next link the next set.

Whenever possible, we should push this kind of processing to the database. Relational database engines are built for this kind of thing, with decades of maths underlying how they work.

So, instead of our controller looking something like this:

we ask the database to do the work:

This tells ActiveRecord to ask the database to sort the people for us (by adding an ORDER BY clause to the SELECT statement). We can couple this with some basic pagination like so:

So now, we only return the 100 newest people.

That also means that we no longer need any sorting logic in the view – which just becomes

Much much simpler.

One last point – if you do have millions of records, your database will probably need a bit of help when doing the sorting. So create a new migration and add an index on there:

Indexes in relational databases are a bit like voodoo – everything can be running fine and then you add in one new record and everything collapses. But adding them in when you know you’re going to be sorting by that field costs little (it’s not totally free but you will be fine until you get to huge datasets) and is definitely worth doing.