ruby-on-railspostgresqlactiverecordpaper-trail-gem

Why isn't order() taking effect on papertrail version associations?


I am using papertrail gem to track versions of my Problem and Outcome models.

I can successfully order Papertrail::Versions like so:

PaperTrail::Version.order(created_at: :desc).limit(1).select(:id)
  PaperTrail::Version Load (0.3ms)  SELECT "versions"."id" FROM "versions" ORDER BY "versions"."created_at" DESC LIMIT $1  [["LIMIT", 1]]
=> [#<PaperTrail::Version:0x00007f4d90820f20 id: 32>]


PaperTrail::Version.order(created_at: :asc).limit(1).select(:id)
  PaperTrail::Version Load (0.9ms)  SELECT "versions"."id" FROM "versions" ORDER BY "versions"."created_at" ASC LIMIT $1  [["LIMIT", 1]]
=> [#<PaperTrail::Version:0x00007f4d90935500 id: 10>]

But when I try the same thing via an association then order() doesn't seem to take effect!

To illustrate, here's an outcome object, it has 9 associated versions:

Outcome.last.versions.count
  Outcome Load (0.4ms)  SELECT "outcomes".* FROM "outcomes" ORDER BY "outcomes"."id" DESC LIMIT $1  [["LIMIT", 1]]
  PaperTrail::Version Count (0.4ms)  SELECT COUNT(*) FROM "versions" WHERE "versions"."item_id" = $1 AND "versions"."item_type" = $2  [["item_id", 1], ["item_type", "Outcome"]]
=> 9

The created_at sort should return different version records but they don't. :/

Outcome.last.versions.order(created_at: :asc).limit(1).select(:id)
  Outcome Load (0.5ms)  SELECT "outcomes".* FROM "outcomes" ORDER BY "outcomes"."id" DESC LIMIT $1  [["LIMIT", 1]]
  PaperTrail::Version Load (0.5ms)  SELECT "versions"."id" FROM "versions" WHERE "versions"."item_id" = $1 AND "versions"."item_type" = $2 ORDER BY "versions"."created_at" ASC, "versions"."id" ASC LIMIT $3  [["item_id", 1], ["item_type", "Outcome"], ["LIMIT", 1]]
=> [#<PaperTrail::Version:0x00007f4d83e6f140 id: 29>]


Outcome.last.versions.order(created_at: :desc).limit(1).select(:id)
  Outcome Load (0.4ms)  SELECT "outcomes".* FROM "outcomes" ORDER BY "outcomes"."id" DESC LIMIT $1  [["LIMIT", 1]]
  PaperTrail::Version Load (0.4ms)  SELECT "versions"."id" FROM "versions" WHERE "versions"."item_id" = $1 AND "versions"."item_type" = $2 ORDER BY "versions"."created_at" ASC, "versions"."id" ASC, "versions"."created_at" DESC LIMIT $3  [["item_id", 1], ["item_type", "Outcome"], ["LIMIT", 1]]
=> [#<PaperTrail::Version:0x00007f4d83e66e00 id: 29>]

Solution

  • OK- as I was writing this out I realised there may be a default scope... and sure enough there is. The answer is to use .unscoped when querying associations e.g.

    Outcome.last.versions.unscoped.order(created_at: :desc).limit(1).select(:id)