I use the AR includes method to execute the LEFT OUTER JOIN between the User and Building objects, where the User may or may not have the Building association:
users = User.includes(:building).references(:buildings)
Since I use references , any related building objects will be loaded.
My assumption was that after that I could iterate over the list of users and check if the building is associated with it, not related to additional requests, but I see that in fact whenever I try to access the property of the user's building that doesn't have one, AR makes another SQL call to try to restore this building (although on subsequent attempts it will just return zero).
These requests are clearly redundant, since the association would be loaded during the initial merge and seems to defeat the whole goal of active loading with inclusion / links, since now I look through N times the number of requests equal to the number of empty associations.
users.each do | user | # This will trigger a new query when building is not present: # SELECT "buildings".* FROM "buildings" WHERE "buildings"."address" = $1 LIMIT 1 [["address", "123 my street"]] if user.building puts 'User has building' else puts 'User has no building' end end
User Class:
class User < ActiveRecord::Base belongs_to :building, foreign_key: 'residence_id' end
Is there a way to check for user associations without causing additional queries?
ON RAILS 4.2.0 / POSTGRES
UPDATE:
Thanks @BoraMa for matching this test . It looks like we get different behavior in recent versions of Rails:
OUTPUT (RAILS 4.2.0):
User 1 has building User 2 has building User 3 has no building D, [2016-05-26T11:48:38.147316 #11910] DEBUG -- : Building Load (0.2ms) SELECT "buildings".* FROM "buildings" WHERE "buildings"."id" = $1 LIMIT 1 [["id", 123]] User 4 has no building
OUTPUT (RAILS 4.2.6)
User 1 has building User 2 has building User 3 has no building User 4 has no building
OUTPUT (RAILS 5.0.0)
User 1 has building User 2 has building User 3 has no building User 4 has no building
Take aways:
- This question was limited to "hanging foreign keys" (for example, the residence_id column is not zero, but there is no corresponding building object) "(THANKS @FrederickCheung)
- Problem resolved with Rails 4.2.6