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

>> class User < ApplicationRecord >> validates :name , presence: true >> end => { :presence => true } >> User . first SELECT "users" . * FROM "users" ORDER BY "users" . "id" ASC LIMIT $1 [[ "LIMIT" , 1 ]] => #<User id: 1, name: "Amit", created_at: "2019-03-11 00:18:41", updated_at: "2019-03-11 00:18:41"> >> User . last SELECT "users" . * FROM "users" ORDER BY "users" . "id" DESC LIMIT $1 [[ "LIMIT" , 1 ]] => #<User id: 2, name: "Mark", created_at: "2019-03-11 00:20:42", updated_at: "2019-03-11 00:20:42"> >> class User < ApplicationRecord >> validates :name , presence: true >> self . implicit_order_column = "updated_at" >> end => Traceback ( most recent call last ): 2 : from ( irb ): 10 1 : from ( irb ): 12 :in '<class:User>' NoMethodError ( undefined method 'implicit_order_column=' for #<Class:0x00007faf4d6cb408>)

Rails 6.0.0.beta2

>> class User < ApplicationRecord >> validates :name , presence: true >> end => { :presence => true } >> User . first SELECT "users" . * FROM "users" ORDER BY "users" . "id" ASC LIMIT $1 [[ "LIMIT" , 1 ]] => #<User id: 1, name: "Amit", created_at: "2019-03-11 00:18:41", updated_at: "2019-03-11 00:18:41"> >> User . last SELECT "users" . * FROM "users" ORDER BY "users" . "id" DESC LIMIT $1 [[ "LIMIT" , 1 ]] => #<User id: 2, name: "Mark", created_at: "2019-03-11 00:20:42", updated_at: "2019-03-11 00:20:42"> >> class User < ApplicationRecord >> validates :name , presence: true >> self . implicit_order_column = "updated_at" >> end => "updated_at" >> User . find ( 1 ). touch SELECT "users" . * FROM "users" WHERE "users" . "id" = $1 LIMIT $2 [[ "id" , 1 ], [ "LIMIT" , 1 ]] UPDATE "users" SET "updated_at" = $1 WHERE "users" . "id" = $2 [[ "updated_at" , "2019-03-11 00:23:33.369021" ], [ "id" , 1 ]] => true >> User . first SELECT "users" . * FROM "users" ORDER BY "users" . "updated_at" ASC LIMIT $1 [[ "LIMIT" , 1 ]] => #<User id: 2, name: "Mark", created_at: "2019-03-11 00:20:42", updated_at: "2019-03-11 00:23:09"> >> User . last SELECT "users" . * FROM "users" ORDER BY "users" . "updated_at" DESC LIMIT $1 [[ "LIMIT" , 1 ]] => #<User id: 1, name: "Amit", created_at: "2019-03-11 00:18:41", updated_at: "2019-03-11 00:23:33">

Here is the relevant pull request.