rails: AR::Relation::Calculations.count breaks relations with group and select
See runnable code example in gist.
Goal: get a count of rows from a query that includes pseudo columns and grouping.
When counting with grouping in the relation, ActiveRecord tries to return group counts instead of a total count and drops the SELECT on the floor. If there are pseudo-columns in the SELECT for grouping, this breaks the whole query.
Also, if it even worked, this would return a hash instead of a Fixnum. There doesn’t seem to be a way to get the total of returned rows, ignoring the grouping.
countshould be usable to return a numeric count even when grouping is needed for the query.relation.countandrelation.all.countshould have the same semantics.countshould work directly on any relation, so the relation can still be used as a chainable scope.
Suggestion for Rails 4: The Calculations#count method is too ambiguous and assumes too much. Change Calculations#count method to only return groups if a :group option is passed directly to the count method, i.e. do not trigger grouped counts based on other group_values in the relation. That, or split #count and #count_grouped into separate methods. This might make it easier to do the right thing with the query builder.
A simple first step might be to flag the relation so that it conditionally delegates .count to .all.count when the above situation occurs. Thoughts?
About this issue
- Original URL
- State: closed
- Created 12 years ago
- Comments: 21 (19 by maintainers)
I’m also having this problem when paginating the results of a query with
ARelin a.groupcall (supposedly,Kaminari.paginatecallscountunder the hood).Here’s some interesting facts:
On Rails 3.2.2
On Rails 3.2.7
Notice the funny column name in the last query. Looks definitely like somewhere
obj.to_s.underscoreis called on an object which doesn’t expect it.As a workaround, I separately store the scope for pagination(without grouping), and chain a
.groupcall only when fetching the data itself. But I suppose, pretty many people use pagination so this is a common use case and should be addressed.