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.