Rails: как загрузить 2 модели через соединение? - PullRequest
3 голосов
/ 24 августа 2009

Я новичок в rails и буду признателен за помощь в оптимизации использования моей базы данных.

Есть ли способ загрузить две модели, связанные друг с другом, одним запросом к БД?

У меня есть две модели Персона и Изображение:

class Person < ActiveRecord::Base
  has_many :images
end

class Image < ActiveRecord::Base
  belongs_to :person
end

Я бы хотел загрузить группу людей и связанные с ними изображения за одну поездку в БД с помощью команды соединения. Например, в SQL я могу загрузить все нужные мне данные с помощью следующего запроса:

select * from people join images on people.id = images.person_id where people.id in (2, 3) order by timestamp;

Так что я надеялся, что этот фрагмент рельсов сделает то, что мне нужно:

>> people_and_images = Person.find(:all, :conditions => ["people.id in (?)", "2, 3"], :joins => :images, :order => :timestamp)

Этот код выполняет ожидаемый оператор SQL и загружает нужные мне экземпляры Person. Однако я вижу, что доступ к изображениям человека приводит к дополнительному запросу SQL.

>> people_and_images[0].images


Image Load (0.004889)   SELECT * FROM `images` WHERE (`images`.person_id = 2)

Использование опции: include в вызове find () действительно загружает обе модели, однако это будет стоить мне дополнительного SELECT, выполнив его вместе с JOIN.

Я бы хотел сделать в Rails то, что я могу сделать в SQL, то есть собрать все необходимые данные одним запросом.

Любая помощь будет принята с благодарностью. Спасибо!

Ответы [ 2 ]

2 голосов
/ 24 августа 2009

Вы хотите использовать :include как

Person.find(:all, :conditions => ["people.id in (?)", "2, 3"], :include => :images, :order => :timestamp)

Ознакомьтесь с документацией по поиску подробнее

0 голосов
/ 24 августа 2009

Вы можете использовать: include для активной загрузки ассоциаций, и действительно он вызывает ровно 2 запроса вместо одного, как в случае: join; первый запрос - загрузка основной модели, а второй - загрузка связанных моделей. Это особенно полезно при решении печально известной проблемы N + 1, с которой вы столкнетесь, если не будете использовать: include и: join не загружают ассоциации.

разница между использованием: joins и: include составляет на 1 запрос больше для: include, но разница с использованием: include будет намного больше.

Вы можете проверить это здесь: http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations

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