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