我不理解Rails includes
方法以及我喜欢的方法,我遇到了一个我希望澄清的问题。我有一个{strong> Board 模型has_many :members
和has_many :lists
(以及列表has_many :cards
)。在以下板控制器中,show
方法如下所示:
def show
@board = Board.includes(:members, lists: :cards).find(params[:id])
...
end
为什么需要includes
方法?为什么我们不能使用@board = Board.find(params[:id])
,然后通过@board.members
和@board.lists
访问成员和列表?我想我并没有真正理解为什么我们需要预取。如果有人可以详细说明为什么这在SQL查询方面更有效,那就太棒了。谢谢!
答案 0 :(得分:3)
根据Rails文档:
预先加载是加载相关记录的机制 Model.find使用尽可能少的查询返回的对象。
当您只是加载记录并稍后查询其不同的关系时,您每次都必须运行查询。举个例子,也来自Rails文档:
clients = Client.limit(10)
clients.each do |client|
puts client.address.postcode
end
此代码执行11次数据库调用以执行非常简单的操作,因为它必须每次执行一次查找。
将上述代码与此示例进行比较:
clients = Client.includes(:address).limit(10)
clients.each do |client|
puts client.address.postcode
end
此代码执行数据库调用2次,因为所有必要的关联都包含在开头。
Here's a link to the pertinent section of the Rails docs.
<强>附加
最近需要注意的一点:如果您使用相关模型执行更复杂的查询,请执行以下操作:
Board.includes(:members, lists: :cards).where('members.color = ?', 'foo').references(:members)
您需要确保包含附加的references(:used_eager_loaded_class)
以完成查询。