Read more

Preloaded associations are filtered by conditions on the same table

Arne Hartherz
December 09, 2010Software engineer at makandra GmbH

When you eagerly load an association list using the .include option, and at the same time have a .where on an included table, two things happen:

  1. Rails tries to load all involved records in a huge single query spanning multiple database tables.
  2. The preloaded association list is filtered by the where condition, even though you only wanted to use the where condition to filter the containing model.
Illustration UI/UX Design

UI/UX Design by makandra brand

We make sure that your target audience has the best possible experience with your digital product. You get:

  • Design tailored to your audience
  • Proven processes customized to your needs
  • An expert team of experienced designers
Read more Show snapshot

The second case's behavior is mostly unexpected, because pre-loaded associations usually don't care about the circumstances under which their containing model was found.


Take this class:

class Activity
  has_many :users

Here activity 42 has four users:

activity = Activity.find(42)
# => [1, 2, 3, 4]

Let's say we want to do the same on all activities that belong to a user. To this, we scope on Activity.
Note how the activity from above now suddenly no longer contains any other users:

activity = Activity.
  .where(users: { id: [4] })
activity.users.ids # here happens the unexpected
# => [4]

By reloading the object, its full list of associated users is restored:

# => [1, 2, 3, 4]

Or you can reset the association cache:

activity.users.reset # newer Rails
activity.users(true) # old Rails

In newer Rails versions you should prefer to use joins and then preload if necessary (which will trigger a second query):

# Join for the condition, but do not preload
activities = Activity.joins(:users).where(users: { id: [4] })

# Preload associations with a second query on users;
# Does not make a join.
activities = activities.preload(:users)
Posted by Arne Hartherz to makandra dev (2010-12-09 15:08)