Рельсы имеют activerecord захватить все необходимые ассоциации за один раз? - PullRequest
1 голос
/ 04 января 2012

У меня есть комментарий модели, который имеет_a Пользователь.

На моей странице отображения я делаю Comment.all, а затем отображаю каждый комментарий.

В представлении мне нужно отобразить не только комментарий, но и информацию о связанном пользователе (то есть авторе).

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

Это нормально и все, но activerecord переводит этов один SELECT * FROM users WHERE USER.id = commentId запрос на каждый комментарий, который я имею.

Это немного нелепо, особенно на странице с сотнями комментариев.(Это сотни отдельных отдельных обращений к БД!)

Когда я делаю Comment.all, можно ли поручить рельсам не только захватывать комментарии, но и захватывать связанных пользователей, а затем, когда я звонюcomment.user.blah позже, чтобы он снова не взял его из базы данных?(Таким образом, все это делается в одном выражении db).

Ответы [ 3 ]

4 голосов
/ 04 января 2012

Вы должны использовать .includes.

Из документа :

Решение проблемы N + 1 запросов

Active Record позволяет заранее указать все ассоциации, которые будут загружены. Это возможно, указав метод include вызова Model.find. С помощью включений Active Record обеспечивает загрузку всех указанных ассоциаций с использованием минимально возможного количества запросов.

Возвращаясь к описанному выше случаю, мы могли бы переписать Client.all для использования активных адресов загрузки:

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

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

Или, в вашем случае, это будет

Comment.includes(:user)
2 голосов
/ 04 января 2012

Вы можете сделать это легко с ActiveRecord, вам просто нужно использовать функцию eager loading .Таким образом, Comment.all(:include => :user) будет выполнять один большой запрос вместо одного запроса на запись.

0 голосов
/ 28 апреля 2015

Оформить заказ http://stackoverflow.com/questions/29908230/rails-have-activerecord-grab-more-than-one-association-in-one-go/29908317#29908317, если вы хотите связать с более чем одной ассоциацией в операторе includes.

Суть использования Comment.includes(:user, :dates, :whatevertableetc).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...