mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Move Relation calculation methods to a separate module
This commit is contained in:
parent
8f5d9eb0e2
commit
e8ca22d129
3 changed files with 54 additions and 45 deletions
|
@ -48,6 +48,7 @@ module ActiveRecord
|
||||||
autoload :Attributes
|
autoload :Attributes
|
||||||
autoload :AutosaveAssociation
|
autoload :AutosaveAssociation
|
||||||
autoload :Relation
|
autoload :Relation
|
||||||
|
autoload :RelationalCalculations
|
||||||
autoload :Base
|
autoload :Base
|
||||||
autoload :Batches
|
autoload :Batches
|
||||||
autoload :Calculations
|
autoload :Calculations
|
||||||
|
|
|
@ -4,6 +4,7 @@ module ActiveRecord
|
||||||
delegate :length, :collect, :map, :each, :all?, :to => :to_a
|
delegate :length, :collect, :map, :each, :all?, :to => :to_a
|
||||||
attr_reader :relation, :klass, :associations_to_preload, :eager_load_associations
|
attr_reader :relation, :klass, :associations_to_preload, :eager_load_associations
|
||||||
|
|
||||||
|
include RelationalCalculations
|
||||||
def initialize(klass, relation, readonly = false, preload = [], eager_load = [])
|
def initialize(klass, relation, readonly = false, preload = [], eager_load = [])
|
||||||
@klass, @relation = klass, relation
|
@klass, @relation = klass, relation
|
||||||
@readonly = readonly
|
@readonly = readonly
|
||||||
|
@ -204,20 +205,6 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def count(*args)
|
|
||||||
column_name, options = construct_count_options_from_args(*args)
|
|
||||||
distinct = options[:distinct] ? true : false
|
|
||||||
|
|
||||||
column = if @klass.column_names.include?(column_name.to_s)
|
|
||||||
Arel::Attribute.new(@relation.table, column_name)
|
|
||||||
else
|
|
||||||
Arel::SqlLiteral.new(column_name == :all ? "*" : column_name.to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
relation = select(column.count(distinct))
|
|
||||||
@klass.connection.select_value(relation.to_sql).to_i
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy_all
|
def destroy_all
|
||||||
to_a.each {|object| object.destroy}
|
to_a.each {|object| object.destroy}
|
||||||
reset
|
reset
|
||||||
|
@ -351,36 +338,5 @@ module ActiveRecord
|
||||||
}.join(',')
|
}.join(',')
|
||||||
end
|
end
|
||||||
|
|
||||||
def construct_count_options_from_args(*args)
|
|
||||||
options = {}
|
|
||||||
column_name = :all
|
|
||||||
|
|
||||||
# We need to handle
|
|
||||||
# count()
|
|
||||||
# count(:column_name=:all)
|
|
||||||
# count(options={})
|
|
||||||
# count(column_name=:all, options={})
|
|
||||||
# selects specified by scopes
|
|
||||||
|
|
||||||
# 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?
|
|
||||||
when 1
|
|
||||||
if args[0].is_a?(Hash)
|
|
||||||
column_name = @relation.send(:select_clauses).join(', ') if @relation.respond_to?(:projections) && @relation.projections.present?
|
|
||||||
options = args[0]
|
|
||||||
else
|
|
||||||
column_name = args[0]
|
|
||||||
end
|
|
||||||
when 2
|
|
||||||
column_name, options = args
|
|
||||||
else
|
|
||||||
raise ArgumentError, "Unexpected parameters passed to count(): #{args.inspect}"
|
|
||||||
end
|
|
||||||
|
|
||||||
[column_name || :all, options]
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
52
activerecord/lib/active_record/relational_calculations.rb
Normal file
52
activerecord/lib/active_record/relational_calculations.rb
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
module ActiveRecord
|
||||||
|
module RelationalCalculations
|
||||||
|
|
||||||
|
def count(*args)
|
||||||
|
column_name, options = construct_count_options_from_args(*args)
|
||||||
|
distinct = options[:distinct] ? true : false
|
||||||
|
|
||||||
|
column = if @klass.column_names.include?(column_name.to_s)
|
||||||
|
Arel::Attribute.new(@relation.table, column_name)
|
||||||
|
else
|
||||||
|
Arel::SqlLiteral.new(column_name == :all ? "*" : column_name.to_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
relation = select(column.count(distinct))
|
||||||
|
@klass.connection.select_value(relation.to_sql).to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def construct_count_options_from_args(*args)
|
||||||
|
options = {}
|
||||||
|
column_name = :all
|
||||||
|
|
||||||
|
# We need to handle
|
||||||
|
# count()
|
||||||
|
# count(:column_name=:all)
|
||||||
|
# count(options={})
|
||||||
|
# count(column_name=:all, options={})
|
||||||
|
# selects specified by scopes
|
||||||
|
|
||||||
|
# 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?
|
||||||
|
when 1
|
||||||
|
if args[0].is_a?(Hash)
|
||||||
|
column_name = @relation.send(:select_clauses).join(', ') if @relation.respond_to?(:projections) && @relation.projections.present?
|
||||||
|
options = args[0]
|
||||||
|
else
|
||||||
|
column_name = args[0]
|
||||||
|
end
|
||||||
|
when 2
|
||||||
|
column_name, options = args
|
||||||
|
else
|
||||||
|
raise ArgumentError, "Unexpected parameters passed to count(): #{args.inspect}"
|
||||||
|
end
|
||||||
|
|
||||||
|
[column_name || :all, options]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue