У меня есть несколько n + 1 запросов, которые делают время загрузки для моего сайта очень медленным. Это веб-сайт в социальных сетях, как и Facebook, а источник n + 1 запросов - друзья. Подробная информация -Rails - исключение n + 1 запросов без объединения таблиц
Таблица друзей содержит 3 столбца - User_id (пользователь, который отправил запрос), friend_id (пользователь, который получил запрос), и в ожидании, что является логическим, чтобы указать, была ли принята дружба или нет.
запросы Дружить реализованы в моей модели пользователя с помощью
def friend_requests
friend_ids = Friendship.where('friend_id = ? AND pending = true', self.id).all
end
Я специально нужна дружба идентификатор, потому что нужно обновить ожидающий булево, если пользователь хочет, чтобы принять или отклонить запрос.
Модель Дружбы имеет ассоциацию belongs_to => friend.
belongs_to :friend,
class_name: "User",
foreign_key: :friend_id,
primary_key: :id
Источник n + 1. Для представления, когда я хочу получить запросы друга, полученные пользователем, я также хочу указать имя и профиль пользователя, отправившего запрос. Это выглядит некоторые вещи, как это -
json.friend_requests @user.friend_requests.includes(friend: :name) do |friendship|
json.extract! friendship, :id, :user_id
json.name User.find(friendship.user_id).name # n + 1
json.profile_pic User.find(friendship.user_id).profile_piC# n + 1
end
я первоначально были некоторые сомнения по поводу синтаксиса включает в себя (друг:: название), но я попробовал все перестановки, упомянутые в this thread, но это дает мне
Ассоциация с именем 'name' не была найдена на пользователе; возможно, вы с ошибкой это?
Это верно, так как имя является атрибутом Пользователя, а не ассоциацией.
Единственный способ решить эту проблему так, что я могу думать, это мой меняю стол friend_requests к find_by_sql запроса, который выглядит следующим образом -
SELECT f.id, f.user_id, f.friend_id, f.pending, users.name, users.profile_pic
FROM friendship AS f
JOIN users ON users.id = friendship.friend_id
WHERE f.friend_id = ? AND pending = true
Это даст мне имя и profile_pic из пользователь, но я не хочу этого делать, поскольку он выглядит грязным, но, что более важно, я хочу знать, есть ли лучший и разумный способ сделать это.
Semi связанных http://stackoverflow.com/a/26251892/525478 –