mislav / will_paginate

Pagination library for Rails and other Ruby applications
http://github.com/mislav/will_paginate/wikis
MIT License
5.7k stars 864 forks source link

Count for grouped queries are not correct #331

Open homerlex opened 11 years ago

homerlex commented 11 years ago

Rails 3.2.13, will_paginate 3.0.4

When I have a query that does grouping the result count coming from will_paginate is incorrect due to the way the query is built up for counts.

I'm thinking this may possibly be an AREL or ActiveRecord problem but I bring it up here because I would think that the problem would have been experienced here and I'm wondering if there are potentially any fixes or workarounds.

I found that if I replace the rel.count call in the WillPaginate::ActiveRecord::RelationMethods count method with rel.all.count I get the proper count.

Does anyone have any thoughts on this issue?

The AREL I have that duplicates this issue look something like:

records = MyModel.select('sum(something)').group[:user_id, :category_id]

ZenCocoon commented 10 years ago

Same here with the query:

SELECT  "activities".* FROM "activities" INNER JOIN "activity_orders" ON "activity_orders"."activity_id" = "activities"."id" WHERE "activities"."destination_id" IN (45) AND "activities"."published" = 't' GROUP BY activities.id, activity_orders.id, activity_orders.position  ORDER BY "activity_orders"."position" ASC LIMIT 9 OFFSET 0

count is being used to calculate the total_entries while I believe it should have relied on size.

Note: A temporary solution that I use, is to force total_entries in the paginate call.

homerlex commented 10 years ago

Just curious why this has not been fixed. Is there something more complicated than what I did as a workaround in the count method (as described in my first comment).

noniq commented 10 years ago

Using relation.all.count does work, but it will load the complete result set into memory. This is something you normally want to avoid.

homerlex commented 10 years ago

So, what would be a proper, more performant fix to will_paginate?

noniq commented 10 years ago

I don’t think it is fixable – ActiveRecord will always do a “count per group” if the query contains a group statement (see https://github.com/rails/rails/issues/7121 and similar issues).

My workaround in a similar case recently: I did a second, manually crafted SQL query to get the correct total number of rows, then I used WillPaginate::Collection.create to create the paginated collection (see http://rdoc.info/gems/will_paginate/WillPaginate/Collection.create for an example).