Product has_many :assets
Asset belongs_to :product
Asset has_attached_file :photo
using Paperclip (with all your standard Paperclip options; a few styles, S3 storage).
If I form a Product query like p = Product.includes(:assets)
I can call each of the actual attributes of Asset without incurring any additional database queries, like:
p = Product.includes(:assets)
p.each { |a| print a.assets.first.开发者_JAVA技巧title }
The title
attribute on Asset
(which is a database column) prints, no queries made.
To get the URL generated by Paperclip:
p = Product.includes(:assets)
p.each { |a| print a.assets.first.photo.url }
causes a separate additional query for each Product
:
Product Load (0.3ms) SELECT "products".* FROM "products" WHERE "products"."id" = 2 LIMIT 1
According to this G.Groups posting, I shouldn't be hitting the database with each pass through the loop, but I am.
Is there a way to not incur the additional database hit for each iteration, but gather all the data all at once? Am I overlooking something simple?
Rails 3.0.9, REE 1.8.7, Paperclip 2.3.11.
updated, fixed
The issue is that in my Paperclip settings, I have :product_id
as part of the :path
: :attachment/:product_id/:filename-:style.:extension
, which is causing the additional Product query for each iteration through the loop.
By changing the query to p = Product.includes(:assets => [:product]).all
, it removed the additional query.
We can get to the root of the problem much faster if you use one of the query analyzer plugins Try query-reviewer, or if you're using newrelic, the dev mode includes this. You'll get a stack trace for every query. I don't think it has anything to do with eager loading - if it did, you'd be getting extra Asset loads instead of Product loads.
I think you're overlooking something simple:
p = Product.includes(:assets).all
includes
sets the relation to eager load the association, all
does the actual query.
irb(main):001:0> p = Product.includes(:assets)
=> ..........
irb(main):002:0> p.class
=> ActiveRecord::Relation
irb(main):003:0> p.all.class
=> Array
精彩评论