rails/rails — Issue #4718: Redundant queries with Identity Map in STI model
Author: GearHead90
Created: 2012-01-27 08:20:24+00:00
State: open

Clear Rails 3.2.1, PG adapter, such classes:

class Event < ActiveRecord::Base
end

class Report < ActiveRecord::Base
end

class VideoReport < Report
end

from the console:

ruby-1.9.3-p0 :021 > ActiveRecord::IdentityMap.use { t1 = Event.find(1); t2 = Event.find(1); t3 = Event.find(1); t1.object_id == t3.object_id && t3.object_id == t2.object_id }
Event Load (0.5ms) SELECT "events".* FROM "events" WHERE "events"."id" = $1 LIMIT 1 [["id", 1]]
Event Loaded From Identity Map (id: 1)
Event Loaded From Identity Map (id: 1)
=> true
ruby-1.9.3-p0 :022 > ActiveRecord::IdentityMap.use { t1 = Report.find(1); t2 = Report.find(1); t3 = Report.find(1); t1.object_id == t3.object_id && t3.object_id == t2.object_id }
Report Load (0.5ms) SELECT "reports".* FROM "reports" WHERE "reports"."id" = $1 LIMIT 1 [["id", 1]]
Report Load (0.4ms) SELECT "reports".* FROM "reports" WHERE "reports"."id" = $1 LIMIT 1 [["id", 1]]
VideoReport Loaded From Identity Map (id: 1)
Report Load (0.3ms) SELECT "reports".* FROM "reports" WHERE "reports"."id" = $1 LIMIT 1 [["id", 1]]
VideoReport Loaded From Identity Map (id: 1)
=> true
ruby-1.9.3-p0 :023 > ActiveRecord::IdentityMap.use { t1 = VideoReport.find(1); t2 = VideoReport.find(1); t3 = VideoReport.find(1); t1.object_id == t3.object_id && t3.object_id == t2.object_id }
VideoReport Load (0.5ms) SELECT "reports".* FROM "reports" WHERE "reports"."type" IN ('VideoReport') AND "reports"."id" = $1 LIMIT 1 [["id", 1]]
VideoReport Load (0.4ms) SELECT "reports".* FROM "reports" WHERE "reports"."type" IN ('VideoReport') AND "reports"."id" = $1 LIMIT 1 [["id", 1]]
VideoReport Loaded From Identity Map (id: 1)
VideoReport Load (0.3ms) SELECT "reports".* FROM "reports" WHERE "reports"."type" IN ('VideoReport') AND "reports"."id" = $1 LIMIT 1 [["id", 1]]
VideoReport Loaded From Identity Map (id: 1)
=> true

You can see, that Event's Identity Map works well, while VideoReport/Report Identity Map loads the same entity, while doing redundant queries for each .find()