Reputation: 1891
I have several related models: Category
has_many
Question
. Question
has_many
Answer
. I need:
Question
has Answer
Count all Questions, that has at least one Answer
(how many Questions inside Category
has Answers)
Get all Categories, where all Questions has 0 Answers
Category
, that has not Answers).EDIT
If I want get list of categories with answers and list of categories without answers?
cats = []
@categories_with_answers = Category.all.each do |cat|
cats << cat if cat.questions.joins(:answers).count > 0
end
How I can write this snippet in more cleaner way?
Upvotes: 1
Views: 1643
Reputation: 11235
You can use includes
and joins
to query relationships:
Category.joins(questions: :answers)
Question.joins(:answers).count
Category.includes(questions: :answers).where(questions: { answers: { question_id: nil }})
Question.includes(:answers).where(answers: { question_id: nil })
There's a good blog article that discusses these approaches in more detail here: https://www.pagerduty.com/blog/sql-left-join-trick/.
EDIT
For an individual category, the query is similar:
@category = Category.find(params[:category_id])
@category.questions.joins(:answers).count
This would be equivalent to:
Question.joins(:answers).where(questions: { category_id: @category.id }).count
The same principle applies to includes
...
@category.questions.includes(:answers).where(answers: { question_id: nil })
Upvotes: 1