Стремительная загрузка для двух ассоциаций той же модели - PullRequest
2 голосов
/ 14 марта 2012

Как быстро загрузить эти ассоциации одним запросом

class Pair < ActiveRecord::Base
  belongs_to :user
  belongs_to :buddy, :class_name => "User"
end


class PairsController < ApplicationController
  def show
    @pair = Pair.includes(:user, :buddy).find(params[:id])
  end
end

запрос выглядит следующим образом:

Парная загрузка (3,1 мс) SELECT pairs. * FROM pairs ГДЕ pairs. id = 935029848 ПРЕДЕЛ 1

Пользовательская нагрузка (4,3 мс) ВЫБРАТЬ users.id ОТ users ГДЕ users. id IN (965902799)

Пользовательская нагрузка (0,9 мс) ВЫБРАТЬ users.id ОТ users ГДЕ users. id IN (274512568)

, но я хочу получить:

парная нагрузка (3,1 мс) SELECT pairs. * ОТ pairs ГДЕ pairs. id = 935029848 LIMIT 1

Пользовательская нагрузка (4,3 мс) SELECT users.id FROM usersГДЕ users. id В (965902799, 274512568)

Ответы [ 3 ]

1 голос
/ 14 марта 2012

Я думаю, что вы не можете сделать это в rails прямо сейчас, потому что rails по умолчанию предполагает, что разные ассоциации имеют разные таблицы, и он не может объединять включения из разных ассоциаций в один запрос во время загрузки, даже если эти ассоциации имеютта же таблица.

ОБНОВЛЕНИЕ : Более того, я думаю, что это даже неосуществимо, потому что если вы думаете о ваших отношениях данных: вы пытаетесь загрузить пользователя и друга для пары,когда вы делаете это с 2 запросами, это довольно просто, вы знаете, кто пользователь, а кто приятель, но подумайте о случае, когда вы делаете это с 1 запросом, как вы узнаете, является ли найденная запись пользователем или приятелем?Там нет никакого способа узнать, что 100%.

0 голосов
/ 21 марта 2013

Я верю, что вы можете сделать это.Вы можете использовать параметр: include (Rails 2) или метод include (Rails 3) соответственно при выполнении поиска ActiveRecord.Вот пример загрузки двух моделей, связанных с постом блога: теги и комментарии.Комментарии также имеют вложенный комментарий:

# Rails 2
Blogpost.all(:include => [:tags, { :comments => :commenter }])

# Rails 3
Blogpost.includes(:tags, { :comments => :commenter }).all
0 голосов
/ 14 марта 2012

Попробуйте @pair = Pair.joins(:user, :buddy).find(params[:id])

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