Ruby on Rails - 可以在 .map() 方法中进行预加载吗?

Ruby on Rails - Possible to eager load within a .map() method?

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

比如我有以下的:

tag_images = tags.map(&:images)

在其他地方,每个 tag_images 都可以通过 image.parent_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"

Tag.rb

has_many :image_tags
has_many :images, through: :image_tags

发生的事情是它正在处理一系列一个或多个标签以及 "collecting" 所有与它们关联的图像(因此使用 tags.map(&:images))。稍后,每个图像的 parent_image 都用 image.parent_image.

引用

所以理想情况下,当它通过 "collect" tag_images 时,有没有办法可以 'get' 相关联的 parent_image最初的 .map 方法(或者可能是其他一些更合适的查询)?

有什么想法吗?

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

假设您有一个变量 tags,其中包含 enumerbleTag(如 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}) 位的更多信息。