mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Relation#count should look for projections in chained relations and perform the count on the given column
Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
This commit is contained in:
parent
aa1b32ae97
commit
00cd3789f6
2 changed files with 28 additions and 3 deletions
|
@ -109,11 +109,11 @@ module ActiveRecord
|
|||
# TODO : relation.projections only works when .select() was last in the chain. Fix it!
|
||||
case args.size
|
||||
when 0
|
||||
select = @relation.send(:select_clauses).join(', ') if @relation.respond_to?(:projections) && @relation.projections.present?
|
||||
select = get_projection_name_from_chained_relations
|
||||
column_name = select if select !~ /(,|\*)/
|
||||
when 1
|
||||
if args[0].is_a?(Hash)
|
||||
select = @relation.send(:select_clauses).join(', ') if @relation.respond_to?(:projections) && @relation.projections.present?
|
||||
select = get_projection_name_from_chained_relations
|
||||
column_name = select if select !~ /(,|\*)/
|
||||
options = args[0]
|
||||
else
|
||||
|
@ -165,5 +165,20 @@ module ActiveRecord
|
|||
column ? column.type_cast(value) : value
|
||||
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
|
||||
|
|
|
@ -376,7 +376,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
|
||||
|
@ -418,6 +418,9 @@ 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)
|
||||
|
@ -435,4 +438,11 @@ class RelationTest < ActiveRecord::TestCase
|
|||
assert_no_queries { assert_equal 5, best_posts.size }
|
||||
end
|
||||
|
||||
def test_count_complex_chained_relations
|
||||
posts = Post.select('comments_count').where('id is not null').group("author_id").where("comments_count > 0")
|
||||
|
||||
expected = { 1 => 2 }
|
||||
assert_equal expected, posts.count
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue