Eager load children in ActiveRecord
Using includes to eager load active record relationships
Sometimes when making queries for objects using activerecord, it makes sense to eager load relationships. Eager loading is the process of retrieving a set of records and collecting the ids in which to do a bulk query to populate the related objects. The act of preloading the relationships makes the queries faster and reduces the amount of queries in your overall result.
Let’s jump to an example to give you an idea how this works. Below is the model relationship we will use:
class Account < ActiveRecord::Base
belongs_to :user
has_many :transactions
attr_accessible :created_at
end
class User < ActiveRecord::Base
has_many :accounts
end
class Transaction < ActiveRecord::Base
belongs_to :account
end
Now that we have our set of models defined, let’s jump into how we work with eager loading in active record queries. When we want to get the user for a set of accounts prepopulated, we would use the keyword includes
.
Example, get accounts and eager load user:
# This will load users in a query "select * from users where id in (x,y,z)" based on user ids of the accounts collected.
accounts = Account.includes(:user).where(created_at: Time.now.utc.iso8601)
What about situations where we need to eager load the user on the account when we have a list of transactions? Well, let’s jump right into answering that. The includes
method supports sub-relationship definitions to a certain depth.
Example, get transactions and eager load the user:
# This will load users which is defined in the array of the account relationship inclusion.
transactions = Transaction.includes(account:[:user]).where(created_at: Time.now.utc.iso8601)
The array is defining the relationships of account
, where account
is a relationship to the transaction. This can be nested quite deep if you wanted to include the account on the user for instance.
More details on this can be found in eager-loading-multiple-associations.