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 :category
和belongs_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,Ransack:如何在 HABTM 关系中搜索“所有”匹配项而不是“任何”匹配项