导轨具有ActiveRecord的抢一气呵成所有需要的关联? [英] Rails have activerecord grab all needed associations in one go?

查看:380
本文介绍了导轨具有ActiveRecord的抢一气呵成所有需要的关联?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模型评论,这has_a用户。

在我的显示页面,我做了 Comment.all ,然后显示每个评论。

在认为我需要显示不仅是评论,也对相关的用户(即作者)的信息。

 <%@ comments.each办|评论| %>
    &其中;%= comment.user.name%GT;
    &其中;%= comment.user.email%​​GT;
    ...等等...
<%结束%GT;
 

这是美好的,而是ActiveRecord的这种转换成一个 SELECT * FROM用户WHERE USER.id = commentId 每次每个评论的查询我有。

这是一个有点可笑,尤其是在有数百条评论页面。 (这是数百个独立的DB命中!)

当我做了Comment.all,有没有去告诉Rails不仅抢了意见,而且还抢了相关的用户,然后当我后来打电话comment.user.blah,因为它不抓住它从数据库了吗? (这样,它会做这一切在1分贝语句)。

解决方案

您应该使用 .includes

DOC

  

解决N + 1查询问题

     

活动记录,您可以预先指定所有将要加载的关联。这是可能的,通过指定包括Model.find呼叫的方法。用包括,活动记录可确保所有指定协会使用查询的最小可能数被加载。

     

重新审视上述情况下,我们可以把Client.all使用贪婪加载地址:

 客户端= Client.includes(:地址).limit(10)

clients.each做|客户端|
  把client.address.post code
结束
 

或者,你的情况,这将是

  Comment.includes(:用户)
 

I have a model Comment, which has_a User.

In my display page, I am doing a Comment.all, and then displaying each comment.

In the view I need to display not only the comment, but also information about the associated user (ie the author).

<% @comments.each do |comment| %>
    <%= comment.user.name %>
    <%= comment.user.email %>
    ...etc...
<% end %>

This is fine and all, but activerecord translates this into one SELECT * FROM users WHERE USER.id = commentId query per EACH comment I have.

This is a little ridiculous, especially on a page with hundreds of comments. (That's hundreds of individual separate DB hits!)

When I am doing the Comment.all, is there away to tell rails to not only grab the comments, but also grab the associated users, and then when I call comment.user.blah later, for it to not grab it from db again? (This way it would do it all in one db statement).

解决方案

You should use .includes.

From the doc:

Solution to N + 1 queries problem

Active Record lets you specify in advance all the associations that are going to be loaded. This is possible by specifying the includes method of the Model.find call. With includes, Active Record ensures that all of the specified associations are loaded using the minimum possible number of queries.

Revisiting the above case, we could rewrite Client.all to use eager load addresses:

clients = Client.includes(:address).limit(10)

clients.each do |client|
  puts client.address.postcode
end

Or, in your case, it would be

Comment.includes(:user)

这篇关于导轨具有ActiveRecord的抢一气呵成所有需要的关联?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆