When loading models in the following manner:
# from models/entry.rb:
has_many :users, :through => :ownerships
# from models/ownership.rb
# loading code
entries = Entry.where("<whatever>").includes(:users)
The expectation is that entries.first.users.loaded? will return true. However, this fails when all of the associated ownership objects have user_id set to NULL. The preload does actually occur - it simply doesn't return any results, which is correct.
This works as expected when the where AREL call is omitted and the preloading occurs as two separate SQL queries (without the LEFT OUTER JOIN clauses).
I believe that the issue arises because of the following line at active_record/associations/join_dependency.rb:191:
# Should first call record.association(join_part.reflection.name).loaded!
return if row[join_part.aliased_primary_key].nil?
The obvious fix would be to check for a collection association and call loaded! even if no records are found to make preloading behavior consistent across the board and in line with expectations - calling include(:users) and then having entry.users.loaded? return false is obviously unexpected.
Can anyone see any problems with fixing the issue in the way I outlined above?
Ensure empty has_many :through association preloaded via joins is mar…
…ked as loaded. Fixes #2054.