4

I recently broke up my query into 4 named scopes to make it easier to re-sort and will paginate which otherwise always worked fine now has problems calculating the number of pages.

  named_scope :loc, lambda { |id| { :conditions => ['location_id = ?', id ] } }
  named_scope :datem, lambda { |*args| { :joins => :scannables, :conditions => [ "scannables.bookdate BETWEEN ? and ?", (args[0].to_date || 3.days.from_now), (args[0].to_date+(args[1] || 3)) ], :group => 'scannables.hostel_id', :having => 'SUM(scannables.available) > ' + ((args[1] || 3).to_i-1).to_s } }
  named_scope :order_by_external_desc, :include => :external_ratings, :order => 'SUM(scannables.available) DESC, external_ratings.rating DESC'
  named_scope :order_by_external_asc, :include => :external_ratings, :order => 'SUM(scannables.available) DESC, external_ratings.rating ASC'

Used like so with paginate thrown on the end...

@location = Place.loc(params[:id]).datem(user_cart.getDate,user_cart.getDays).order_by_external_desc.paginate(:per_page => 15, :page => params[:page])

Paginate will for example show that there are 6 pages of 15 each but when you get to page 4, pages 5-6 disappear... and if you try jumping to 5 or 6 directly they don't exist.

Looking at it, I realized to problem will paginate is having is that

c=@location = Place.loc(params[:id]).datem(user_cart.getDate,user_cart.getDays).order_by_external_desc.size

c = 78

however

c=@location = Place.loc(params[:id]).datem(user_cart.getDate,user_cart.getDays).order_by_external_desc

c.size = 56

The sql getting generated for the former is about 8 lines shorter than that of the latter and neglects my sql HAVING clause which causes it to return more results...

Any ideas on how to fix this?

4

1 回答 1

0

当使用 group_by/have 时——就像你在 datem named_scope 中所做的那样——不幸的是,ActiveRecord 的计数错误。我认为您对此无能为力。我也不确定这是否一定是 ActiveRecord 中的错误 - 或者只是在使用 ActiveRecord 时由于生成的 SQL 的性质而实际上无法正确计算的东西。

无论哪种方式 - 您都需要解决这个“错误”。

这样做的方法是在单独的 SQL 语句中处理计数(给您正确结果的语句),并将其添加到分页结果中,如下所示:

total_entries = Place.count(sql) # or the combinations of named_scopes etc with a .size or whichever one gives you the correct count

Place.scopes.paginate(:per_page => 15, :page => params[:page], :total_entries => total_entries) # where scopes are all of your named scopes as you have in your examples
于 2012-04-17T09:15:02.403 回答