Rails ActiveRecord:如何通过两个多态关联来加载对象

时间:2012-04-18 10:38:06

标签: ruby-on-rails activerecord

我正在尝试在查询Comment表时急切加载Activity

# Activity (basic FB-style news feed)
#   user_id
#   primary_source_id (polymorphic object, like "Post", that can have comments)
#   primary_source_type

# Comment (acts as commentable w/ threading gem)
#   user_id
#   commentable_id
#   commentable_type

# WHAT GOES HERE?!
# How do I eager-load comments?
activities = Activity.includes(???).joins(???)

# Display code
activities.each do |activity|
  render ... # render activity
  activity.root_comments.each do |comment|
    render ... # render activity's comments
  end
end

请参阅,我通过循环浏览Activity并抓取每个primary_source(如Post)及其Comment来渲染我的网页。现在primary_source正在急切加载,但Comment不是;每个循环都会点击Comment表。这对我来说是一个巨大的性能打击,它与我展示的Activity的数量呈线性关系。

如何急切加载我的Comment

1 个答案:

答案 0 :(得分:3)

假设您的所有primary_source都是可评论的,

activities = Activity.includes(:user, :primary_source => :comment_threads).where...

......为我工作。为了避免命中数据库(并且破坏了包含的目的),你必须用comment_threads(包括子注释)替换对root_comments的任何引用。这是因为root_comments实际上是在gem(lib / acts_as_commentable_with_threading.rb)中定义为辅助方法:

def root_comments
  self.comment_threads.where(:parent_id => nil)
end

来源:关于嵌套关联的Rails Guide部分,以及在acts_as_commentable_with_threading gem中窥视以及在控制台中进行一些试验和错误:)