急切加载Paperclip的has_attached_file数据?

时间:2011-06-27 23:33:27

标签: ruby-on-rails paperclip eager-loading

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}},它删除了其他查询。

2 个答案:

答案 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,则开发模式包括此项。您将获得每个查询的堆栈跟踪。我不认为它与急切加载有任何关系 - 如果确实如此,你将获得额外的资产加载而不是产品加载。