Forward ActiveRecord::Relation#count to Enumerable#count

Rohit Arolkar

By Rohit Arolkar

on May 1, 2017

This blog is part of our  Rails 5.1 series.

Let's say that we want to know all the deliveries in progress for an order.

The following code would do the job.

1
2class Order
3  has_many :deliveries
4
5  def num_deliveries_in_progress
6    deliveries.select { |delivery| delivery.in_progress? }.size
7  end
8
9end
10

But usage of count should make more sense over a select, right?

1
2class Order
3  has_many :deliveries
4
5  def num_deliveries_in_progress
6    deliveries.count { |delivery| delivery.in_progress? }
7  end
8
9end
10

However the changed code would return count for all the order deliveries, rather than returning only the ones in progress.

That's because ActiveRecord::Relation#count silently discards the block argument.

Rails 5.1 fixed this issue.

1
2module ActiveRecord
3  module Calculations
4
5    def count(column_name = nil)
6      if block_given?
7        to_a.count { |*block_args| yield(*block_args) }
8      else
9        calculate(:count, column_name)
10      end
11    end
12
13  end
14end
15

So now, we can pass a block to count method.

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, ReactJS, React Native, remote work,open source, engineering & design.