Rails包含何时添加的方法

时间:2018-03-20 15:41:54

标签: ruby-on-rails ruby-on-rails-4 activerecord eager-loading

所以我已经阅读了很多关于rails includes方法的内容,但我仍然对使用它的最佳情况感到困惑。

我的情况是我有user条记录,然后此用户与多个模型相关,例如clientplayergameteam_playerteamserverserver_center

我需要在视图中显示相关模型的特定属性。我只需要来自特定模型的大约1-2个属性,而我不使用其他属性。

我已添加delegates例如从server.name获取player我可以使用server_name但在这种情况下我include所有表格我需要这些属性,或者我还有其他的东西,因为我只需要模型中的一些属性。

目前我的查询如下:

@user_profile = User
               .includes({:client => [:player, :team_player => [:team]]}, 
                        :game, 
                        {:server_center => :server})
               .where(game_id: @master.admin.games)

1 个答案:

答案 0 :(得分:1)

包含可确保使用尽可能少的查询加载所有指定的关联。

假设我们有2个名为用户个人资料的模型:

class User < ActiveRecord::Base
  has_one :profile
end

class Profile < ActiveRecord::Base
  belongs_to :user
end

如果我们正在遍历每个users并显示每个用户的名称,则名称字段位于个人资料模型中,该模型与用户相关联对于model,我们通常每次都必须使用单独的数据库查询来检索名称。但是,当使用includes方法时,它已经急切地加载了关联的人员表,因此这个块只需要一个查询。

不包含:

users = User.all
users.each do |user|
  puts user.profile.name # need extra database query for each time we call name
end

包含

# 1st query to get all users 2nd to get all profiles and loads to the memory
users = User.includes(:profile).all
users.each do |user|
  puts user.profile.name # no extra query needed instead it loads from memory.
end

急切加载用于防止 N + 1查询问题。基本上它是左外连接,这在加速请求响应或优化查询方面起着重要作用。例如:如果我们拥有大量用户,并且我们想要遍历这些用户及其相应的个人资料。没有时间,我们将击中数据库将等于用户数量。但是如果我们正在使用include,那么当我们遍历它将从这个内存中获取而不是查询的用户时,它会将所有配置文件保存到内存中。

急切加载对于我们的 N + 1查询可能并不总是最好的方法,例如:如果您正在处理一些复杂的查询,最好寻找一些缓存解决方案喜欢俄罗斯娃娃缓存等。但这两种方法都有自己的专业优势。当天结束时,由您决定最佳方法。

有助于检测N + 1查询的一个有用的宝石是bullet