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)
You can do this easily with ActiveRecord, you just need to use the eager loading feature in it. So Comment.all(:include => :user)
will run one large query rather than one query per record.
Checkout http://stackoverflow.com/questions/29908230/rails-have-activerecord-grab-more-than-one-association-in-one-go/29908317#29908317
if you want to associate with more than one association in the includes
statement.
The gist is using Comment.includes(:user, :dates, :whatevertableetc)
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.