急切加载 Paperclip 的 has_attached_file 数据?

发布于 2024-11-17 08:09:59 字数 1312 浏览 1 评论 0原文

Product has_many :assets

Asset own_to :product

Asset has_attached_file :photo 使用回形针(包含所有标准回形针选项;一些样式、S3 存储) 。

如果我形成像 p = Product.includes(:assets) 这样的 Product 查询,我可以调用 Asset 的每个实际属性,而不会产生任何额外的数据库查询,例如:

p = Product.includes(:assets)
p.each { |a| print a.assets.first.title }

titleAsset(这是一个数据库列)上的 > 属性打印,不进行任何查询。

要获取由 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

根据 这个 G.Groups 帖子,我不应该在每次循环时都访问数据库,但我确实这样做了。

有没有一种方法可以避免每次迭代产生额外的数据库命中,而是一次性收集所有数据?我是否忽略了一些简单的事情?

Rails 3.0.9、REE 1.8.7、回形针 2.3.11。

已更新,已修复

问题是在我的回形针设置中,我将 :product_id 作为 :path 的一部分::attachment/ :product_id/:filename-:style.:extension,这会导致循环中每次迭代进行额外的 Product 查询。

通过将查询更改为 p = Product.includes(:assets => [:product]).all,它删除了附加查询。

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.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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

岛徒 2024-11-24 08:09:59

如果您使用查询分析器插件之一尝试查询审查器,或者如果您使用 newrelic,那么我们可以更快地找到问题的根源,开发模式包括此功能。您将获得每个查询的堆栈跟踪。我不认为它与急切加载有任何关系 - 如果确实如此,您将获得额外的资产加载而不是产品加载。

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.

旧伤慢歌 2024-11-24 08:09:59

我认为您忽略了一些简单的事情:

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文