My development environment is on Rails 4.1 and postgresql
I've 3 models with has_many through relationship:
class Item < ActiveRecord::Base
has_many :item_parts
has_many :parts, through: :item_parts
end
class Part < ActiveRecord::Base
has_many :item_parts
has_many :items, through: :item_parts
end
class ItemPart < ActiveRecord::Base
belongs_to :item
belongs_to :part
end
The item_parts join table has a unit_count attribute to keep track of how many parts the item contains.
When in the view I iterate through all parts of a specific item I also need to get the unit_count value from the join table.
This give me the n+1 query issue.
I tried to eager load the join table:
item.parts.includes(:item_parts)
ItemPart Load (0.5ms) SELECT "item_parts".* FROM "item_parts" WHERE "item_parts"."part_id" IN (24, 12, 3, 26)
but when after I do:
part.item_parts.where(item_id: item.id).first.unit_count
I got following sql query for every part; the eager loading didn't work
ItemPart Load (0.5ms) SELECT "item_parts".* FROM "item_parts" WHERE "item_parts"."part_id" = $1 AND "item_parts"."item_id" = $2 [["part_id", 24], ["item_id", 18]]
Any suggestions?
I expect this is because you are using the "count" method which, according to:
http://dev.mensfeld.pl/2014/09/activerecord-count-vs-length-vs-size-and-what-will-happen-if-you-use-it-the-way-you-shouldnt/
"is not stored internally during object life cycle, which means, that each time we invoke this method, SQL query is performed again"
Try using .length or .size methods instead.
Note: (to quote the article)
length – collection.length
size – collection.size