Forward ActiveRecord::Relation#count to Enumerable#count

Rohit Arolkar

Rohit Arolkar

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.


class Order
  has_many :deliveries

  def num_deliveries_in_progress
    deliveries.select { |delivery| delivery.in_progress? }.size
  end

end

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


class Order
  has_many :deliveries

  def num_deliveries_in_progress
    deliveries.count { |delivery| delivery.in_progress? }
  end

end

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.


module ActiveRecord
  module Calculations

    def count(column_name = nil)
      if block_given?
        to_a.count { |*block_args| yield(*block_args) }
      else
        calculate(:count, column_name)
      end
    end

  end
end

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

If this blog was helpful, check out our full blog archive.

Stay up to date with our blogs.

Subscribe to receive email notifications for new blog posts.