Skip to content

Instantly share code, notes, and snippets.

@miloops
Created December 29, 2009 19:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save miloops/265514 to your computer and use it in GitHub Desktop.
Save miloops/265514 to your computer and use it in GitHub Desktop.
From 166815cde49599cca0d7d69921abd533984a78d6 Mon Sep 17 00:00:00 2001
From: Emilio Tagua <miloops@gmail.com>
Date: Mon, 28 Dec 2009 17:07:47 -0300
Subject: [PATCH] Fix: count should look for projections in chained relations and perform the count on the given column.
---
.../lib/active_record/relational_calculations.rb | 19 +++++++++++++++++--
activerecord/test/cases/relations_test.rb | 10 +++++++++-
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/activerecord/lib/active_record/relational_calculations.rb b/activerecord/lib/active_record/relational_calculations.rb
index 10eb992..93457ff 100644
--- a/activerecord/lib/active_record/relational_calculations.rb
+++ b/activerecord/lib/active_record/relational_calculations.rb
@@ -31,10 +31,10 @@ module ActiveRecord
# TODO : relation.projections only works when .select() was last in the chain. Fix it!
case args.size
when 0
- column_name = @relation.send(:select_clauses).join(', ') if @relation.respond_to?(:projections) && @relation.projections.present?
+ column_name = get_projection_name_from_chained_relations
when 1
if args[0].is_a?(Hash)
- column_name = @relation.send(:select_clauses).join(', ') if @relation.respond_to?(:projections) && @relation.projections.present?
+ column_name = get_projection_name_from_chained_relations
options = args[0]
else
column_name = args[0]
@@ -48,5 +48,20 @@ module ActiveRecord
[column_name || :all, options]
end
+ def get_projection_name_from_chained_relations
+ name = nil
+ if @relation.respond_to?(:projections) && @relation.projections.present?
+ name = @relation.send(:select_clauses).join(', ')
+ elsif @relation.respond_to?(:relation) && relation = @relation.relation
+ while relation.respond_to?(:relation)
+ if relation.respond_to?(:projections) && relation.projections.present?
+ name = relation.send(:select_clauses).join(', ')
+ end
+ relation = relation.relation
+ end
+ end
+ name
+ end
+
end
end
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index ded4f2f..5531edb 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -341,7 +341,7 @@ class RelationTest < ActiveRecord::TestCase
relations = []
relations << (Post.order('comments.id DESC') & Post.eager_load(:last_comment) & Post.scoped)
relations << (Post.eager_load(:last_comment) & Post.order('comments.id DESC') & Post.scoped)
-
+
relations.each do |posts|
post = posts.find { |p| p.id == 1 }
assert_equal Post.find(1).last_comment, post.last_comment
@@ -383,9 +383,17 @@ class RelationTest < ActiveRecord::TestCase
Post.update_all(:comments_count => nil)
posts = Post.scoped
+ assert_equal 0, posts.select('comments_count').where('id is not null').order('id').count
+ assert_equal 0, posts.where('id is not null').select('comments_count').count
assert_equal 7, posts.select('comments_count').count('id')
assert_equal 0, posts.select('comments_count').count
assert_equal 0, posts.count(:comments_count)
assert_equal 0, posts.count('comments_count')
end
+
+ def test_count_complex_chained_relations
+ posts = Post.scoped
+
+ assert_equal 2, posts.select('comments_count').where('id is not null').group("author_id").where("comments_count > 0").count
+ end
end
--
1.6.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment