Rails active record querying association with 'exists'

You can also use a subquery:

members.where(id: Response.select(:member_id))

In comparison to something with includes it will not load the associated models (which is a performance benefit if you do not need them).


You can use includes and then test if the related response(s) exists like this:

def surveys_completed
  members.includes(:responses).where('responses.id IS NOT NULL')
end

Here is an alternative, with joins:

def surveys_completed
  members.joins(:responses)
end

The solution using Rails 4:

def surveys_completed
  members.includes(:responses).where.not(responses: { id: nil })
end

Alternative solution using activerecord_where_assoc: This gem does exactly what is asked here: use EXISTS to to do a condition. It works with Rails 4.1 to the most recent.

members.where_assoc_exists(:responses)

It can also do much more!


Similar questions:

  • How to query a model based on attribute of another model which belongs to the first model?
  • association named not found perhaps misspelled issue in rails association
  • Rails 3, has_one / has_many with lambda condition
  • Rails 4 scope to find parents with no children
  • Join multiple tables with active records

You can use SQL EXISTS keyword in elegant Rails-ish manner using Where Exists gem:

members.where_exists(:responses).count

Of course you can use raw SQL as well:

members.where("EXISTS" \
  "(SELECT 1 FROM responses WHERE responses.member_id = members.id)").
  count