Search code examples
ruby-on-railsactiverecordjoineager-loading

Rails 3: How to eager load an association AND apply a condition with includes()?


My app has Question models that has_many UserResponse models.

I'd like to get the last 5 questions that a particular User has answered with the associated UserResponse objects filtered on the user_id field.

Here's what I currently have:

Question.group("questions.id").
joins("inner join user_responses r on r.question_id = questions.id").
where("r.user_id = #{user_id}").
order("questions.id asc").limit(5)

This query gives me back what I want, but the problem is when I get a Question out of the array and do question.user_responses the result is all of the responses for that question, not just the ones that should be filtered by the join/where clause above.

I've tried to do this:

Question.includes(:user_responses).group("questions.id").
joins("inner join user_responses r on r.question_id = questions.id").
where("r.user_id = #{user_id}").
order("questions.id asc").limit(5)

thinking it would eager load each response...but it doesn't appear to function that way.

Where am I going wrong?

If it makes a difference, the reason I need everything eagerly loaded is because I want to take the array and call to_json on it and return the json from a web service for my mobile app, so I need the entire graph available.


Solution

  • I think you're trying to get too complicated here. How about the following?

    Question
      .includes(:user_responses)
      .where("user_id = ?", user_id)
      .order("questions.id asc")
      .limit(5)