diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2006-02-20 03:15:22 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2006-02-20 03:15:22 +0000 |
commit | 377bdd02b9daba35113299262a98060763925959 (patch) | |
tree | c5db590773c64d334b81a42291d01a6030c1fc84 | |
parent | 03acf48817d38e8ec4078d50f6ab48a2dfc035b3 (diff) | |
download | rails-377bdd02b9daba35113299262a98060763925959.tar.gz rails-377bdd02b9daba35113299262a98060763925959.tar.bz2 rails-377bdd02b9daba35113299262a98060763925959.zip |
Added :count option to pagination that'll make it possible for the ActiveRecord::Base.count call to using something else than * for the count. Especially important for count queries using DISTINCT #3839 [skaes]. Added :select option to Base.count that'll allow you to select something else than * to be counted on. Especially important for count queries using DISTINCT (closes #3839) [skaes].
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3620 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r-- | actionpack/CHANGELOG | 2 | ||||
-rw-r--r-- | actionpack/lib/action_controller/pagination.rb | 9 | ||||
-rw-r--r-- | actionpack/test/activerecord/pagination_test.rb | 19 | ||||
-rw-r--r-- | activerecord/CHANGELOG | 2 | ||||
-rwxr-xr-x | activerecord/lib/active_record/base.rb | 2 | ||||
-rwxr-xr-x | activerecord/test/base_test.rb | 24 |
6 files changed, 52 insertions, 6 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 25fe245388..3336572189 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Added :count option to pagination that'll make it possible for the ActiveRecord::Base.count call to using something else than * for the count. Especially important for count queries using DISTINCT #3839 [skaes] + * Update script.aculo.us to V1.5.2 [Thomas Fuchs] * Added element and collection proxies to RJS [DHH]. Examples: diff --git a/actionpack/lib/action_controller/pagination.rb b/actionpack/lib/action_controller/pagination.rb index 2f1a1d985c..630b244a0e 100644 --- a/actionpack/lib/action_controller/pagination.rb +++ b/actionpack/lib/action_controller/pagination.rb @@ -71,6 +71,7 @@ module ActionController :order => nil, :join => nil, :joins => nil, + :count => nil, :include => nil, :select => nil, :parameter => 'page' @@ -119,6 +120,10 @@ module ActionController # and Model.count # <tt>:include</tt>:: optional eager loading parameter passed to Model.find(:all, *params) # and Model.count + # <tt>:select</tt>:: :select parameter passed to Model.find(:all, *params) + # + # <tt>:count</tt>:: parameter passed as :select option to Model.count(*params) + # def paginate(collection_id, options={}) Pagination.validate_options!(collection_id, options, true) paginator_and_collection_for(collection_id, options) @@ -165,7 +170,9 @@ module ActionController # custom counter. def count_collection_for_pagination(model, options) model.count(:conditions => options[:conditions], - :joins => options[:join] || options[:joins], :include => options[:include]) + :joins => options[:join] || options[:joins], + :include => options[:include], + :select => options[:count]) end # Returns a collection of items for the given +model+ and +options[conditions]+, diff --git a/actionpack/test/activerecord/pagination_test.rb b/actionpack/test/activerecord/pagination_test.rb index 00ae78614f..386300c086 100644 --- a/actionpack/test/activerecord/pagination_test.rb +++ b/actionpack/test/activerecord/pagination_test.rb @@ -64,6 +64,14 @@ class PaginationTest < ActiveRecordTestCase :conditions => 'project_id=1') render :nothing => true end + + def paginate_with_join_and_count + @developer_pages, @developers = paginate(:developers, + :join => 'd LEFT JOIN developers_projects ON d.id = developers_projects.developer_id', + :conditions => 'project_id=1', + :count => "d.id") + render :nothing => true + end def rescue_errors(e) raise e end @@ -133,9 +141,16 @@ class PaginationTest < ActiveRecordTestCase def test_paginate_with_join_and_conditions get :paginate_with_joins - expected = assigns(:topics) + expected = assigns(:developers) get :paginate_with_join - assert_equal expected, assigns(:topics) + assert_equal expected, assigns(:developers) + end + + def test_paginate_with_join_and_count + get :paginate_with_joins + expected = assigns(:developers) + get :paginate_with_join_and_count + assert_equal expected, assigns(:developers) end def test_paginate_with_include_and_order diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 8b5fc450f8..ade3e656a8 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Added :select option to Base.count that'll allow you to select something else than * to be counted on. Especially important for count queries using DISTINCT #3839 [skaes] + * Correct syntax error in mysql DDL, and make AAACreateTablesTest run first [Bob Silva] * Allow :include to be used with has_many :through associations #3611 [Michael Schoen] diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index deb3c5fc1f..e040c86505 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -544,7 +544,7 @@ module ActiveRecord #:nodoc: def construct_counter_sql(options) sql = "SELECT COUNT(" sql << "DISTINCT " if options[:distinct] - sql << "#{table_name}.#{primary_key}) FROM #{table_name} " + sql << "#{options[:select] || "#{table_name}.#{primary_key}"}) FROM #{table_name} " sql << " #{options[:joins]} " if options[:joins] add_conditions!(sql, options[:conditions]) sql diff --git a/activerecord/test/base_test.rb b/activerecord/test/base_test.rb index 475e31028a..4349d92eeb 100755 --- a/activerecord/test/base_test.rb +++ b/activerecord/test/base_test.rb @@ -1050,19 +1050,39 @@ class BasicsTest < Test::Unit::TestCase def test_count_with_join res = Post.count_by_sql "SELECT COUNT(*) FROM posts LEFT JOIN comments ON posts.id=comments.post_id WHERE posts.#{QUOTED_TYPE} = 'Post'" - res2 = res + 1 + res2 = nil assert_nothing_raised do res2 = Post.count("posts.#{QUOTED_TYPE} = 'Post'", "LEFT JOIN comments ON posts.id=comments.post_id") end assert_equal res, res2 - res3 = res + 1 + res3 = nil assert_nothing_raised do res3 = Post.count(:conditions => "posts.#{QUOTED_TYPE} = 'Post'", :joins => "LEFT JOIN comments ON posts.id=comments.post_id") end assert_equal res, res3 + + res4 = Post.count_by_sql "SELECT COUNT(p.id) FROM posts p, comments c WHERE p.#{QUOTED_TYPE} = 'Post' AND p.id=c.post_id" + res5 = nil + assert_nothing_raised do + res5 = Post.count(:conditions => "p.#{QUOTED_TYPE} = 'Post' AND p.id=c.post_id", + :joins => "p, comments c", + :select => "p.id") + end + + assert_equal res4, res5 + + res6 = Post.count_by_sql "SELECT COUNT(DISTINCT p.id) FROM posts p, comments c WHERE p.#{QUOTED_TYPE} = 'Post' AND p.id=c.post_id" + res7 = nil + assert_nothing_raised do + res7 = Post.count(:conditions => "p.#{QUOTED_TYPE} = 'Post' AND p.id=c.post_id", + :joins => "p, comments c", + :select => "p.id", + :distinct => true) + end + assert_equal res6, res7 end def test_clear_association_cache_stored |