image by Jeff Frenette
‘Fix’ first & last by explicitly setting implicit ordering
Using UUIDs as primary keys has many benefits. However, it causes issues with Rails’s implicit ordering.
In a previous article, I suggested using named scopes alongside first
and last
, but there is now an easier way to re-enable the default behaviour of Active Record.
Instead of…
…avoiding #first
& #last
when using non-sequential id
s on an Active Record model, or using the extra specificity provided by a named scope…
Use
…implicit_order_column
within your model and aim it at the automatically generated created_at
column.
class Coffee < ApplicationRecord
self.implicit_order_column = "created_at"
end
Why?
There are major benefits to using UUIDs in your database: uniqueness, assignability, and security.
With this one-line change you also retain the benefits of Rails’ .first
and .last
helper methods, provided you assign the implicit_order_column
to the created_at
timestamp.
Why not?
This is a Rails 6 feature. Prior versions of Rails still require the explicit ordering implementation previously explained.
You may still prefer using the explicit ordering approach for greater clarity.
If you do not use UUIDs in your data model, there’s little point in using this.
Note that if two records are created at exactly the same time, the order of the results for those records will be based on the order of their primary key.
Another issue is that, by default, created_at
does not have a database index, unlike the id
primary key. Running the query without the index could take a while if the dataset is very large. You should add an database index on the created_at
field.
Hat tip
My friend Tekin came up with the idea and implemented it in Rails.
Benjamin Alexander for making the point about needing a database index on created_at
.
Last updated on March 1st, 2020