简体   繁体   中英

Rails: how to load 2 models via join?

I am new to rails and would appreciate some help optimizing my database usage.

Is there a way to load two models associated with each other with one DB query?

I have two models Person and Image:

class Person < ActiveRecord::Base
  has_many :images
end

class Image < ActiveRecord::Base
  belongs_to :person
end

I would like to load a set of people and their associated images with a single trip to the DB using a join command. For instance, in SQL, I can load all the data I need with the following query:

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

So I was hoping that this rails snippet would do what I need:

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

This code executes the SQL statement I am expecting and loads the instances of Person I need. However, I see that accessing aa Person's images leads to an additional SQL query.

>> people_and_images[0].images


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

Using the :include option in the call to find() does load both models, however it will cost me an additional SELECT by executing it along with the JOIN.

I would like to do in Rails what I can do in SQL which is to grab all the data I need with one query.

Any help would be greatly appreciated. Thanks!

You want to use :include like

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

Check out the find documentation for more details

You can use :include for eager loading of associations and indeed it does call exactly 2 queries instead of one as with the case of :joins; the first query is to load the primary model and the second is to load the associated models. This is especially helpful in solving the infamous N+1 query problem, which you will face if you doesn't use :include, and :joins doesn't eager-load the associations.

the difference between using :joins and :include is 1 query more for :include, but the difference of not using :include will be a whole lot more.

you can check it up here: http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM