Skip to content

Commit

Permalink
Cope with scoped :select when counting.
Browse files Browse the repository at this point in the history
  • Loading branch information
benpickles authored and mislav committed Sep 12, 2008
1 parent b9d857e commit 5adc2de
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 5 deletions.
19 changes: 14 additions & 5 deletions lib/will_paginate/finder.rb
Expand Up @@ -181,7 +181,19 @@ def method_missing_with_paginate(method, *args, &block) #:nodoc:
# in the database. It relies on the ActiveRecord +count+ method.
def wp_count(options, args, finder)
excludees = [:count, :order, :limit, :offset, :readonly]
unless options[:select] and options[:select] =~ /^\s*DISTINCT\b/i

# we may be in a model or an association proxy
klass = (@owner and @reflection) ? @reflection.klass : self

# Use :select from scope if it isn't already present.
options[:select] = scope(:find, :select) unless options[:select]

if options[:select] and options[:select] =~ /^\s*DISTINCT\b/i
# Remove quoting and check for table_name.*-like statement.
if options[:select].gsub('`', '') =~ /\w+\.\*/
options[:select] = "DISTINCT #{klass.table_name}.#{klass.primary_key}"
end
else
excludees << :select # only exclude the select param if it doesn't begin with DISTINCT
end

Expand All @@ -191,10 +203,7 @@ def wp_count(options, args, finder)
# merge the hash found in :count
# this allows you to specify :select, :order, or anything else just for the count query
count_options.update options[:count] if options[:count]

# we may be in a model or an association proxy
klass = (@owner and @reflection) ? @reflection.klass : self


# forget about includes if they are irrelevant (Rails 2.1)
if count_options[:include] and
klass.private_methods.include?('references_eager_loaded_tables?') and
Expand Down
6 changes: 6 additions & 0 deletions test/finder_test.rb
Expand Up @@ -340,6 +340,12 @@ def test_count_select_when_distinct
Developer.paginate :select => 'DISTINCT salary', :page => 2
end

def test_count_with_scoped_select_when_distinct
Developer.stubs(:find).returns([])
Developer.expects(:count).with(:select => 'DISTINCT users.id').returns(0)
Developer.distinct.paginate :page => 2
end

def test_should_use_scoped_finders_if_present
# scope-out compatibility
Topic.expects(:find_best).returns(Array.new(5))
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/developer.rb
Expand Up @@ -7,6 +7,7 @@ def self.with_poor_ones(&block)
end
end

named_scope :distinct, :select => 'DISTINCT `users`.*'
named_scope :poor, :conditions => ['salary <= ?', 80000], :order => 'salary'

def self.per_page() 10 end
Expand Down

0 comments on commit 5adc2de

Please sign in to comment.