Reputation: 4510
Having the following models
class Release
has_many :sprints
end
class Sprint
has_many :tasks
belongs_to :release
end
class Task
belongs_to :sprint
end
How can I count all the tasks
for an specific release
?
I tried this but it performs two queries and doesn't seem very efficient:
def total_task_count
release = Release.find(1)
Task.where(sprint_id: release.sprints.pluck(:id)).count
end
What's a better way of counting all children associations in a child association?
Also, If I want to do this in a list view:
@releases.each do |release|
<%= release.total_tasks_count %>
end
How can I perform a single query instead of one per release?
Upvotes: 2
Views: 1665
Reputation: 3603
you can do something like this:
def total_task_count
Task.joins(:sprints).merge(Sprint.where(release_id: 1)).count
end
Upvotes: 1
Reputation: 102
As John Feltz mentioned, you can use has_many through
on the Release
model.
To run a all queries at once, you can also use .includes
:
Release.includes(:task).find(#{id_here})
When you call release.tasks.count
, it will already have the data, so it will not run another query. See more about includes
in the API Docs.
Upvotes: 2
Reputation: 560
Add a has_many through
relationship. See the Rails guide
in the release
model, add:
has_many :tasks, through: :sprints
Then you can do
@releases.each do |release|
<%= release.tasks.count %>
end
Upvotes: 4