Product has_many :assets
Asset belongs_to :product
Asset has_attached_file :photo
使用Paperclip(包含所有标准Paperclip选项;一些样式,S3存储)。
如果我形成像p = Product.includes(:assets)
这样的产品查询,我可以调用Asset的每个实际属性,而不会产生任何其他数据库查询,例如:
p = Product.includes(:assets)
p.each { |a| print a.assets.first.title }
title
(数据库列)上的Asset
属性打印,未进行任何查询。
获取Paperclip生成的网址:
p = Product.includes(:assets)
p.each { |a| print a.assets.first.photo.url }
为每个Product
:
Product Load (0.3ms) SELECT "products".* FROM "products" WHERE "products"."id" = 2 LIMIT 1
根据this G.Groups posting,我不应该在每次通过循环时都访问数据库,但我是。
有没有办法不为每次迭代产生额外的数据库命中,但是一次收集所有数据?我忽略了一些简单的事情吗?
Rails 3.0.9,REE 1.8.7,Paperclip 2.3.11。
已更新,已修复
问题在于,在我的回形针设置中,我:product_id
:path
:attachment/:product_id/:filename-:style.:extension
的一部分p = Product.includes(:assets => [:product]).all
,这导致通过循环每次迭代产生额外的产品查询。< / p>
通过将查询更改为{{1}},它删除了其他查询。
答案 0 :(得分:0)
我认为你忽略了一些简单的事情:
p = Product.includes(:assets).all
includes
将关系设置为急切加载关联,all
执行实际查询。
irb(main):001:0> p = Product.includes(:assets)
=> ..........
irb(main):002:0> p.class
=> ActiveRecord::Relation
irb(main):003:0> p.all.class
=> Array
答案 1 :(得分:0)
如果您使用查询分析器插件之一,我们可以更快地找到问题的根源尝试查询 - 审阅者,或者如果您使用的是newrelic,则开发模式包括此项。您将获得每个查询的堆栈跟踪。我不认为它与急切加载有任何关系 - 如果确实如此,你将获得额外的资产加载而不是产品加载。