Rails - 仅根据具体情况引入一些 HABTM 关联,​​以避免不必要的连接

Posted

技术标签:

【中文标题】Rails - 仅根据具体情况引入一些 HABTM 关联,​​以避免不必要的连接【英文标题】:Rails - Only pull in some HABTM associations on a case-by-case basis to avoid unnecessary joins 【发布时间】:2013-07-23 00:05:45 【问题描述】:

在 Rails 4 中,我有一个项目,其中我设置了三个具有以下多对多关系的模型:

一件物品 has_and_belongs_to_many 类别 has_and_belongs_to_many 标签 一个类别 has_and_belongs_to_many 项 标签 has_and_belongs_to_many 项

虽然选择一个项目并自动获取所有关联的类别和标签很容易,但在某些情况下,我想选择项目及其关联的类别,而不是它们的标签。在这些情况下,我想避免对 Tags 表和 ItemsTags 连接表进行额外的数据库连接。任何人都可以帮助我正确查找语法以仅将项目加入类别吗? (旁注:我还计划在项目和其他模型之间添加 10 个额外的多对多关系,但我只是简化了这个问题的场景。最后,我试图避免加入尽可能多的桌子。)

谢谢!

【问题讨论】:

认为您希望Item 模型上的关联为belongs_to,以便Item belongs_to :categorybelongs_to :tag。跨度> 很好,抱歉。意思是把has_and_belongs_to_many。现在更正。 【参考方案1】:

Rails 默认情况下不会加载相关记录,除非您请求它

Item.all 只会从“items”表中获取记录

稍后在您的代码中,如果您调用item.categories,这就是执行查询以获取此特定项目的所有类别的时间点。如果您从不调用item.tags,则永远不会执行对“标签”表的查询,并且不会获取记录。底线是:您可以根据需要拥有任意数量的关联,只要您不明确调用它们,它们就不会被加载。

关于性能的旁注,rails 提供了几种方法来连接和包含关联的表:

Item.include(:category).all 将仅触发 2 个查询以获取所有项目和所有相关类别。

Item.include(:category).joins(:category).all -> 将仅触发 1 个查询加入项目和类别表(但可能比 2 个请求慢)

因此,您可以完全控制从数据库加载的内容。那些也可以申请范围。

【讨论】:

谢谢!我没有意识到这是在幕后发生的(根据需要进行即时检索)。您的 .include() 示例正是我想要的。真的很感谢帮助!我试试看! 更多信息 guides.rubyonrails.org/association_basics.html 和 guides.rubyonrails.org/active_record_querying.html 在 google 上搜索 leazy loading 和 eager loading,这就是你要找的东西 @Benjamin - 抱歉耽搁了。被耽搁了,没有机会马上尝试。感谢您的帮助!

以上是关于Rails - 仅根据具体情况引入一些 HABTM 关联,​​以避免不必要的连接的主要内容,如果未能解决你的问题,请参考以下文章

Rails 3.1 Ransack HABTM

Rails,Ransack:如何在 HABTM 关系中搜索“所有”匹配项而不是“任何”匹配项

Rails:在 HABTM 关系中将子项从大型记录集添加到父模型的 UI

Rails HABTM:通过

Rails 搜索 HABTM 关系中的关联模型

Rails中使用的HABTM关系MySQL表