1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #10710 from senny/5554_let_the_database_raise_on_counts

Remove column restrictions for `#count`, let the database raise if the SQL is invalid.
This commit is contained in:
Jon Leighton 2013-06-09 06:02:56 -07:00
commit f5e133e830
4 changed files with 32 additions and 11 deletions

View file

@ -1,3 +1,19 @@
* Remove column restrictions for `count`, let the database raise if the SQL is
invalid. The previos behavior was untested and surprising for the user.
Fixes #5554.
Example:
User.select("name, username").count
# Before => SELECT count(*) FROM users
# After => ActiveRecord::StatementInvalid
# you can still use `count(:all)` to perform a query unrelated to the
# selected columns
User.select("name, username").count(:all) # => SELECT count(*) FROM users
*Yves Senn*
* Rails now automatically detects inverse associations. If you do not set the
`:inverse_of` option on the association, then Active Record will guess the
inverse association based on heuristics.

View file

@ -247,7 +247,7 @@ module ActiveRecord
def empty?
return @records.empty? if loaded?
c = count
c = count(:all)
c.respond_to?(:zero?) ? c.zero? : c.empty?
end

View file

@ -207,15 +207,18 @@ module ActiveRecord
end
if operation == "count"
column_name ||= (select_for_count || :all)
if select_values.present?
column_name ||= select_values.join(", ")
else
column_name ||= :all
end
unless arel.ast.grep(Arel::Nodes::OuterJoin).empty?
distinct = true
end
column_name = primary_key if column_name == :all && distinct
distinct = nil if column_name =~ /\s*DISTINCT\s+/i
distinct = nil if column_name =~ /\s*DISTINCT[\s(]+/i
end
if group_values.any?
@ -376,13 +379,6 @@ module ActiveRecord
column ? column.type_cast(value) : value
end
def select_for_count
if select_values.present?
select = select_values.join(", ")
select if select !~ /[,*]/
end
end
def build_count_subquery(relation, column_name, distinct)
column_alias = Arel.sql('count_column')
subquery_alias = Arel.sql('subquery_for_count')

View file

@ -167,6 +167,15 @@ class CalculationsTest < ActiveRecord::TestCase
assert_no_match(/OFFSET/, queries.first)
end
def test_count_on_invalid_columns_raises
e = assert_raises(ActiveRecord::StatementInvalid) {
Account.select("credit_limit, firm_name").count
}
assert_match "accounts", e.message
assert_match "credit_limit, firm_name", e.message
end
def test_should_group_by_summed_field_having_condition
c = Account.group(:firm_id).having('sum(credit_limit) > 50').sum(:credit_limit)
assert_nil c[1]