0

我知道预加载是如何以及什么是预加载,并且我在 Google 和 StackOverflow 上搜索过其他预加载问题。其中一些很有启发性,但没有一个能解决我的特定问题,所以我要自己问一个。

这是我的架构:

class Organization < ActiveRecord::Base
  has_many :activities
  has_many :users_logged, source: :user, through: :activities
end

class Activity < ActiveRecord::Base
  belongs_to :user
  belongs_to :organization
end

class User < ActiveRecord::Base
  has_many :activities
end

这个项目是继承的,我不能做任何重大的模式重新设计,所以如果这个问题是不可能的,那么就这样吧。我只是想尝试加快这些报告的生成,其中涉及加载所有组织,例如:

Organizations.includes(:users_logged).joins(:activities)

现在,我在这里意识到这includes(:users_logged)将加载所有活动,但joins(:activities)对于我排除的排序/分组字段仍然是必需的,因为它们对问题并不重要。

现在的问题是,我想为includes(:users_logged)指令选择的所有用户急切加载所有活动,因为我不仅需要组织详细信息、相关活动以及为组织记录活动的所有用户。除此之外,我需要为用户加载所有活动(理想情况下与组织相关,但一旦我弄清楚如何急切加载,我就可以解决这个问题)。

我目前的实现:

@orgs = Organization.includes(:users_logged).joins(:activities).all
@orgs.each do |org|
  org.users_logged.each do |user|
    # Just work with user.activities
  end
end

这导致每个用户的查询平均0.3 ms与当前的测试数据量相加,并且相当快地加起来。有没有办法为一组用户急切加载所有活动?

4

1 回答 1

0

我发布这个答案是为了确保它已经得到解决。一旦我有能力,我会接受这个作为正确答案。

Baldrick 的评论让我开始思考我究竟是如何过滤掉用户的活动,以便我只将活动记录到活动组织中。我在表演:

user.activities.where("organization_id = ?", org.id)

无论我做了什么,这都会强制每次查询。所以我把它改成:

user.activities.select { |o| o.id == org.id }

现在它执行了我想要的(在@Baldrick 的推荐之后)。

于 2013-07-02T07:12:18.273 回答