Back to Blog

Rails 6 adds implicit_order_column

on April 16, 2019
This blog is part of our Rails 6 series.

Rails 6.0 was recently released.

Rails 6 added implicit_order_column on ActiveRecord::ModelSchema which allows us to define a custom column for implicit ordering on the model level. If there is no implicit_order_column defined, Rails takes a primary key as the implicit order column. Also, before Rails 6, the primary key was used to order records implicitly by default.

This has impact on methods like first , last and many more where implicit ordering is used.

Let's checkout how it works.

Rails 5.2

1>> class User < ApplicationRecord
2>>   validates :name, presence: true
3>> end
4
5=> {:presence=>true}
6
7>> User.first
8SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1  [["LIMIT", 1]]
9
10=> #<User id: 1, name: "Amit", created_at: "2019-03-11 00:18:41", updated_at: "2019-03-11 00:18:41">
11
12>> User.last
13SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]
14
15=> #<User id: 2, name: "Mark", created_at: "2019-03-11 00:20:42", updated_at: "2019-03-11 00:20:42">
16
17>> class User < ApplicationRecord
18>>   validates :name, presence: true
19>>   self.implicit_order_column = "updated_at"
20>> end
21
22=> Traceback (most recent call last):
23        2: from (irb):10
24        1: from (irb):12:in '<class:User>'
25NoMethodError (undefined method 'implicit_order_column=' for #<Class:0x00007faf4d6cb408>)

Rails 6.0.0.beta2

1>> class User < ApplicationRecord
2>>   validates :name, presence: true
3>> end
4
5=> {:presence=>true}
6
7>> User.first
8SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1  [["LIMIT", 1]]
9
10=> #<User id: 1, name: "Amit", created_at: "2019-03-11 00:18:41", updated_at: "2019-03-11 00:18:41">
11
12>> User.last
13SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]
14
15=> #<User id: 2, name: "Mark", created_at: "2019-03-11 00:20:42", updated_at: "2019-03-11 00:20:42">
16
17>> class User < ApplicationRecord
18>>   validates :name, presence: true
19>>   self.implicit_order_column = "updated_at"
20>> end
21
22=> "updated_at"
23
24>> User.find(1).touch
25SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
26UPDATE "users" SET "updated_at" = $1 WHERE "users"."id" = $2  [["updated_at", "2019-03-11 00:23:33.369021"], ["id", 1]]
27
28=> true
29
30>> User.first
31SELECT "users".* FROM "users" ORDER BY "users"."updated_at" ASC LIMIT $1  [["LIMIT", 1]]
32
33=> #<User id: 2, name: "Mark", created_at: "2019-03-11 00:20:42", updated_at: "2019-03-11 00:23:09">
34
35>> User.last
36SELECT "users".* FROM "users" ORDER BY "users"."updated_at" DESC LIMIT $1  [["LIMIT", 1]]
37
38=> #<User id: 1, name: "Amit", created_at: "2019-03-11 00:18:41", updated_at: "2019-03-11 00:23:33">
39

Here is the relevant pull request.


You might also like

If you liked this blog post, check out similar ones from BigBinary