Apply the default scope earlier when doing calculations. Fixes #1682.

This commit is contained in:
Jon Leighton 2011-06-23 19:57:49 +01:00
parent 8a1319dec0
commit 87d6865bf7
3 changed files with 24 additions and 5 deletions

@ -146,10 +146,16 @@ def calculate(operation, column_name, options = {})
if options.except(:distinct).present?
apply_finder_options(options.except(:distinct)).calculate(operation, column_name, :distinct => options[:distinct])
else
if eager_loading? || (includes_values.present? && references_eager_loaded_tables?)
construct_relation_for_association_calculations.calculate(operation, column_name, options)
relation = with_default_scope
if relation.equal?(self)
if eager_loading? || (includes_values.present? && references_eager_loaded_tables?)
construct_relation_for_association_calculations.calculate(operation, column_name, options)
else
perform_calculation(operation, column_name, options)
end
else
perform_calculation(operation, column_name, options)
relation.calculate(operation, column_name, options)
end
end
rescue ThrowResult
@ -196,7 +202,7 @@ def operation_over_aggregate_column(column, operation, distinct)
def execute_simple_calculation(operation, column_name, distinct) #:nodoc:
# Postgresql doesn't like ORDER BY when there are no GROUP BY
relation = with_default_scope.reorder(nil)
relation = reorder(nil)
if operation == "count" && (relation.limit_value || relation.offset_value)
# Shortcut when limit is zero.
@ -245,7 +251,7 @@ def execute_grouped_calculation(operation, column_name, distinct) #:nodoc:
"#{field} AS #{aliaz}"
}
relation = with_default_scope.except(:group).group(group.join(','))
relation = except(:group).group(group.join(','))
relation.select_values = select_values
calculated_data = @klass.connection.select_all(relation.to_sql)

@ -498,4 +498,11 @@ def test_default_scope_find_last
lowest_salary_dev = DeveloperOrderedBySalary.find(developers(:poor_jamis).id)
assert_equal lowest_salary_dev, DeveloperOrderedBySalary.last
end
def test_default_scope_include_with_count
d = DeveloperWithIncludes.create!
d.audit_logs.create! :message => 'foo'
assert_equal 1, DeveloperWithIncludes.where(:audit_logs => { :message => 'foo' }).count
end
end

@ -91,6 +91,12 @@ class DeveloperWithSelect < ActiveRecord::Base
default_scope select('name')
end
class DeveloperWithIncludes < ActiveRecord::Base
self.table_name = 'developers'
has_many :audit_logs, :foreign_key => :developer_id
default_scope includes(:audit_logs)
end
class DeveloperOrderedBySalary < ActiveRecord::Base
self.table_name = 'developers'
default_scope :order => 'salary DESC'