所以我已经阅读了很多关于rails includes
方法的内容,但我仍然对使用它的最佳情况感到困惑。
我的情况是我有user
条记录,然后此用户与多个模型相关,例如client
,player
,game
,team_player
,team
,server
和server_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)
答案 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