lkartono
lkartono

Reputation: 2393

Rails: weird behavior when getting last record while ordering

I'm using Rails 6 and I've noticed a strange behavior in Active Record when trying to get the latest record from a collection. Here is what I have:

session.rb

class Session < ApplicationRecord
  has_many :participations
end

participation.rb

class Participation < ApplicationRecord
  belongs_to :session
end

When I'm trying to get the latest participation with:

Participation.order(created_at: :desc).last

The SQL query generated looks like:

SELECT "participations".*
FROM "participations"
ORDER BY "participations"."created_at" ASC
LIMIT $1

Note that I did order(created_at: :desc) but the SQL is using ASC.

However, if I change my code to:

Participation.order(created_at: :asc).last

The SQL query is doing the opposite (a DESC):

SELECT "participations".*
FROM "participations"
ORDER BY "participations"."created_at" DESC
LIMIT $1

Does anyone have an explanation as to why it behave this way ? Is it a Rails bug ? Seems like using last with order is causing this issue. If I remove last, ActiveRecord is generating the correct SQL (using the correct order)

Upvotes: 1

Views: 41

Answers (1)

Mori
Mori

Reputation: 27779

ActiveRecord is optimizing the SQL statement for you. This

Participation.order(created_at: :desc).last

returns the same result as

Participation.order(created_at: :asc).first

But the latter statement is more efficient because it has to traverse fewer rows, so Rails generates SQL as if you had written it that way.

Upvotes: 3

Related Questions