【问题标题】:Ruby on Rails - Possible to eager load within a .map() method?Ruby on Rails - 可以在 .map() 方法中预加载?
【发布时间】:2019-11-14 19:12:41
【问题描述】:

是否可以使用预先加载作为 .map() 方法的一部分?

例如,我有以下内容:

tag_images = tags.map(&:images)

在其他地方,这些 tag_image 中的每一个都有其 parent_image 使用image.parent_image 访问。

子弹 gem 建议我使用 .includes(:parent_image),但我不确定如何在这种情况下应用预加载。

以下是模型适用部分的设置方式...

Image.rb

has_many :image_tags
has_many :tags, through: :image_tags

has_many :crops, class_name: "Image", foreign_key: "parent_image_id"
belongs_to :parent_image, class_name: "Image"

标签.rb

has_many :image_tags
has_many :images, through: :image_tags

它正在经历一系列一个或多个标签并“收集”与它们相关的所有图像(因此使用tags.map(&:images))。稍后,每个图像的parent_image 都被image.parent_image 引用。

因此,理想情况下,虽然它正在“收集”tag_images,但有没有一种方法可以在初始 .map 方法(或者可能是其他一些查询更合适)?

有什么想法吗?

【问题讨论】:

  • 您确定要使用map吗? (顺便说一句,这是一种方法,而不是“命令”。)看起来您可能想要使用查询,但您没有显示有关模型的任何信息,所以很难说。
  • 当然,对不起@jvillian,我回去在模型信息中添加了。这有帮助吗?

标签: ruby-on-rails eager-loading


【解决方案1】:

假设您有一个变量tags,其中包含Tags 的enumerble(如ActiveRecord_Relation),我想您可能想要更多类似的东西:

tag_images = Image.joins(:tags).where(tags: {id: tags}).distinct.includes(:parent_image)

你可能需要也可能不需要.distinct - 你只需要弄乱它就可以看到。

顺便说一句,您可以查看Specifying Conditions on the Joined Tables 文档以了解有关.joins(:tags).where(tags: {id: tags}) 位的更多信息。

【讨论】:

  • 谢谢@jvillian,这正是我需要的!
【解决方案2】:

如果您按照 Bullet 建议的 tag_images = tags.includes(:parent_image) 编写它,它将急切加载包含的关联并将它们添加到内存中。如果您在任何标签实例上调用 parent_image,它不会触发任何额外的查询。

【讨论】:

  • 看来parent_imageImage 上的关联,不是吗? (真的很难说,因为 OP 省略了模型信息。)在这种情况下,tags.includes(:parent_image) 可能不起作用,是吗?
  • 你好@user6500179!我回去并将模型信息添加到我的问题中。你介意再看一遍吗?再次感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多