Back to Blog

Forward ActiveRecord::Relation#count to Enumerable#count

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.


You might also like

If you liked this blog post, check out similar ones from BigBinary