salsify/goldiloader

Too many assiated models may be loaded

Closed this issue · 2 comments

jgrau commented

First of all thanks for a great gem. I use this heavily.

I'll try to explain my problem:

I have a controller action that does something like this

def related
  room = Room.find(params[:id])
  collection = SimilarRooms.call(room: room, limit: 50)
  # collection is now an array of 50 Rooms
  render json: collection
end

The SimilarRooms service (stripped down to what matters):

def call
  similar_rooms = Room.within(100, origin: room) # <- this is the problematic line I think
  # finds all the rooms within 100km of the origin room
  # this returns a lot of rooms
  # ... do some math and some custom ordering ...
  similar_rooms.take(limit) # take the first 50 rooms
end

When I render the collection (which only includes the top 50 rooms) I also include data from an associated company has_one relation. That association is preloaded, however, it looks like it includes the company for every room found in the within query and not just the companies for the 50 rooms in the array that I try to render.

Does this explanation make sense? Is there anything to be done about this?

The explanation makes sense and the behavior you're seeing is expected. You can restrict the scope of models used for automatic eager loading by doing the following from SimilarRooms:

def call
  similar_rooms = Room.within(100, origin: room) # <- this is the problematic line I think
  # finds all the rooms within 100km of the origin room
  # this returns a lot of rooms
  # ... do some math and some custom ordering ...
  result = similar_rooms.take(limit) # take the first 50 rooms
  # Only consider the first 50 rooms when performing automatic eager loading
  Goldiloader::AutoIncludeContext.register_models(results)
  results
end
jgrau commented

Thanks for explaining and for the solution!