Skip to content

Instantly share code, notes, and snippets.

@billhorsman
Created June 22, 2012 08:03
Show Gist options
  • Save billhorsman/2971210 to your computer and use it in GitHub Desktop.
Save billhorsman/2971210 to your computer and use it in GitHub Desktop.
Two simple queries instead of one complex (or impossible) one.
# Problem: the query you want to build to bring back the right objects is complicated. When
# you try and eagerly load the objects you need it all breaks and goes to shit. This often
# happens if you are using "group" or "count", for instance. If you don't eagerly load the
# objects you need then you have an n+1 (or worse) problem as you make an additional query
# for each object you use.
# So try doing the query in two parts: 1) get the primary key for each object you need,
# 2) eagerly load all the objects that match.
# Grab the ids. Don't worry about eagerly loading. The important thing is that it doesn't
# bring back too many rows. If you're paginating then you're probably OK.
ids = Apple.joins(:banana => :carrot).where("complex stuff").paginate(:page => 1).map(&:id)
# Or, this might be even better - use pluck instead of map
ids = Apple.joins(:banana => :carrot).where("complex stuff").paginate(:page => 1).pluck(:id)
# Now, do another query doing a simple match on id.
results = Apple.includes(:donut, :egg_plant, { :fig => :giraffe }).where("apples.id IN (?)", ids)
# This isn't ideal and you lose lots of the benefits of a normal scoped query (lazy execution
# for one).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment