Carlos Martinez
Carlos Martinez

Reputation: 4510

How to count all children records for a has_many association?

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

Answers (3)

sa77
sa77

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

Alex Kitchens
Alex Kitchens

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

John Feltz
John Feltz

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

Related Questions