Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
# add this file as config/initializers/will_paginate_postgresql_count.rb
# in a Rails application
module WillPaginate
module Finder
module ClassMethods
# add '1=1' to paginate conditions as marker such that the select from the pg_class
# is used to approximate simple rows count, e.g.
# Foo.paginate(:page => params[:page], :conditions => "1=1")
def wp_count_with_postgresql(options, args, finder, &block)
if options[:conditions] == ["1=1"] || options[:conditions] == "1=1"
# counting rows in PostgreSQL is slow so use the pg_class table for
# approximate rows count on simple selects
# http://wiki.postgresql.org/wiki/Slow_Counting
# http://www.varlena.com/GeneralBits/120.php
ActiveRecord::Base.count_by_sql "SELECT (reltuples)::integer FROM pg_class r WHERE relkind = 'r' AND relname = '#{self.table_name}'"
else
wp_count_without_postgresql(options, args, finder, &block)
end
end
alias_method_chain :wp_count, :postgresql
end
end
end
@kineticac

This comment has been minimized.

Copy link

commented Dec 14, 2010

There's a problem with the alias_method_chain. Since wp_count is protected, it doesn't seem to work. here's the error:

...aliasing.rb:33:in alias_method': undefined methodwp_count' for module `WillPaginate::Finder::ClassMethods' (NameError)

Any ideas how to alias the protected method?

@monde

This comment has been minimized.

Copy link
Owner Author

commented Dec 14, 2010

That example is real code from a production Rails 2.3.8 application.

@petervojtek

This comment has been minimized.

Copy link

commented Sep 20, 2011

this works for me in Rails 3 and will_paginate 3.0.pre2

module WillPaginate
  module Finders
    module ActiveRecord

      # add '1=1' to paginate conditions as marker such that the select from the pg_class
      # is used to approximate simple rows count, e.g.
      # Foo.paginate(:page => params[:page], :conditions => "1=1")
      def wp_count_with_postgresql(options, args, finder, &block)
        if options[:conditions] == ["1=1"] || options[:conditions] == "1=1"
          # counting rows in PostgreSQL is slow so use the pg_class table for
          # approximate rows count on simple selects
          # http://wiki.postgresql.org/wiki/Slow_Counting
          # http://www.varlena.com/GeneralBits/120.php
          ::ActiveRecord::Base.connection.execute("SELECT (reltuples)::integer FROM pg_class r WHERE relkind = 'r' AND relname = '#{self.table_name}'").first['reltuples'].to_i
        else
          wp_count_without_postgresql(options, args, finder, &block)
        end

      end
      self.send('public', :wp_count)
      alias_method_chain :wp_count, :postgresql
    end
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.