aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/active_relation/primitives/attribute.rb10
-rw-r--r--lib/active_relation/primitives/expression.rb4
-rw-r--r--lib/active_relation/relations.rb2
-rw-r--r--lib/active_relation/relations/aggregation.rb24
-rw-r--r--lib/active_relation/relations/grouping.rb19
-rw-r--r--lib/active_relation/relations/projection.rb4
-rw-r--r--lib/active_relation/relations/relation.rb10
-rw-r--r--spec/active_relation/unit/relations/grouping_spec.rb33
-rw-r--r--spec/active_relation/unit/relations/join_spec.rb2
-rw-r--r--spec/active_relation/unit/relations/projection_spec.rb23
-rw-r--r--spec/active_relation/unit/relations/relation_spec.rb17
11 files changed, 95 insertions, 53 deletions
diff --git a/lib/active_relation/primitives/attribute.rb b/lib/active_relation/primitives/attribute.rb
index d37271490a..5b1ef4d7c0 100644
--- a/lib/active_relation/primitives/attribute.rb
+++ b/lib/active_relation/primitives/attribute.rb
@@ -10,6 +10,10 @@ module ActiveRelation
def alias_or_name
@alias || name
end
+
+ def aggregation?
+ false
+ end
module Transformations
def as(aliaz = nil)
@@ -56,10 +60,8 @@ module ActiveRelation
end
def %(other)
- if other
- (history - other.history) + (other.history - history)
- else
- history
+ if other then (history - other.history) + (other.history - history)
+ else history
end
end
end
diff --git a/lib/active_relation/primitives/expression.rb b/lib/active_relation/primitives/expression.rb
index 2df2888ba0..ae4c61d1b1 100644
--- a/lib/active_relation/primitives/expression.rb
+++ b/lib/active_relation/primitives/expression.rb
@@ -29,6 +29,10 @@ module ActiveRelation
"#{function_sql}(#{attribute.to_sql})" + (@alias ? " AS #{quote_column_name(@alias)}" : '')
end
+ def aggregation?
+ true
+ end
+
def ==(other)
self.class == other.class and
attribute == other.attribute and
diff --git a/lib/active_relation/relations.rb b/lib/active_relation/relations.rb
index 9cede2a6d1..d8e211c853 100644
--- a/lib/active_relation/relations.rb
+++ b/lib/active_relation/relations.rb
@@ -4,7 +4,7 @@ require 'active_relation/relations/compound'
require 'active_relation/relations/writing'
require 'active_relation/relations/table'
require 'active_relation/relations/join'
-require 'active_relation/relations/aggregation'
+require 'active_relation/relations/grouping'
require 'active_relation/relations/projection'
require 'active_relation/relations/selection'
require 'active_relation/relations/order'
diff --git a/lib/active_relation/relations/aggregation.rb b/lib/active_relation/relations/aggregation.rb
deleted file mode 100644
index 62432408e1..0000000000
--- a/lib/active_relation/relations/aggregation.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-module ActiveRelation
- class Aggregation < Compound
- attr_reader :expressions, :groupings
-
- def initialize(relation, options)
- @relation, @expressions, @groupings = relation, options[:expressions], options[:groupings]
- end
-
- def ==(other)
- self.class == other.class and
- relation == other.relation and
- groupings == other.groupings and
- expressions == other.expressions
- end
-
- def attributes
- expressions.collect { |e| e.bind(self) }
- end
-
- def aggregation?
- true
- end
- end
-end \ No newline at end of file
diff --git a/lib/active_relation/relations/grouping.rb b/lib/active_relation/relations/grouping.rb
new file mode 100644
index 0000000000..57323e90f3
--- /dev/null
+++ b/lib/active_relation/relations/grouping.rb
@@ -0,0 +1,19 @@
+module ActiveRelation
+ class Grouping < Compound
+ attr_reader :expressions, :groupings
+
+ def initialize(relation, *groupings)
+ @relation, @groupings = relation, groupings.collect { |g| g.bind(relation) }
+ end
+
+ def ==(other)
+ self.class == other.class and
+ relation == other.relation and
+ groupings == other.groupings
+ end
+
+ def aggregation?
+ true
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/active_relation/relations/projection.rb b/lib/active_relation/relations/projection.rb
index c1495c1742..0f8ea5175c 100644
--- a/lib/active_relation/relations/projection.rb
+++ b/lib/active_relation/relations/projection.rb
@@ -15,5 +15,9 @@ module ActiveRelation
relation == other.relation and
projections == other.projections
end
+
+ def aggregation?
+ attributes.any?(&:aggregation?)
+ end
end
end \ No newline at end of file
diff --git a/lib/active_relation/relations/relation.rb b/lib/active_relation/relations/relation.rb
index b62a5d9fb9..8ab266c53d 100644
--- a/lib/active_relation/relations/relation.rb
+++ b/lib/active_relation/relations/relation.rb
@@ -66,8 +66,8 @@ module ActiveRelation
skipped.blank?? self : Skip.new(self, skipped)
end
- def aggregate(*expressions)
- AggregateOperation.new(self, expressions)
+ def group(*groupings)
+ groupings.all?(&:blank?) ? self : Grouping.new(self, *groupings)
end
module Writes
@@ -90,12 +90,6 @@ module ActiveRelation
Join.new(join_sql, relation1, relation2, *predicates)
end
end
-
- AggregateOperation = Struct.new(:relation, :expressions) do
- def group(*groupings)
- Aggregation.new(relation, :expressions => expressions, :groupings => groupings)
- end
- end
end
include Operations
diff --git a/spec/active_relation/unit/relations/grouping_spec.rb b/spec/active_relation/unit/relations/grouping_spec.rb
new file mode 100644
index 0000000000..4b5badbb8b
--- /dev/null
+++ b/spec/active_relation/unit/relations/grouping_spec.rb
@@ -0,0 +1,33 @@
+require File.join(File.dirname(__FILE__), '..', '..', '..', 'spec_helper')
+
+module ActiveRelation
+ describe Grouping do
+ before do
+ @relation = Table.new(:users)
+ @attribute = @relation[:id]
+ end
+
+ describe '#to_sql' do
+ describe 'when given a predicate' do
+ it "manufactures sql with where clause conditions" do
+ Grouping.new(@relation, @attribute).to_sql.should be_like("
+ SELECT `users`.`id`, `users`.`name`
+ FROM `users`
+ GROUP BY `users`.`id`
+ ")
+ end
+ end
+
+ describe 'when given a string' do
+ it "passes the string through to the where clause" do
+ pending 'it should not quote asdf'
+ Grouping.new(@relation, 'asdf').to_sql.should be_like("
+ SELECT `users`.`id`, `users`.`name`
+ FROM `users`
+ GROUP BY asdf
+ ")
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/spec/active_relation/unit/relations/join_spec.rb b/spec/active_relation/unit/relations/join_spec.rb
index 22b0a9f237..c1a13cee6e 100644
--- a/spec/active_relation/unit/relations/join_spec.rb
+++ b/spec/active_relation/unit/relations/join_spec.rb
@@ -97,8 +97,8 @@ module ActiveRelation
describe 'when joining aggregated relations' do
before do
@aggregation = @relation2 \
- .aggregate(@relation2[:user_id], @relation2[:id].count.as(:cnt)) \
.group(@relation2[:user_id]) \
+ .project(@relation2[:user_id], @relation2[:id].count.as(:cnt)) \
.as('photo_count')
end
diff --git a/spec/active_relation/unit/relations/projection_spec.rb b/spec/active_relation/unit/relations/projection_spec.rb
index 529998a8d4..5936cbc45f 100644
--- a/spec/active_relation/unit/relations/projection_spec.rb
+++ b/spec/active_relation/unit/relations/projection_spec.rb
@@ -53,16 +53,29 @@ module ActiveRelation
end
describe 'when given a string' do
- before do
- @string = "asdf"
- end
-
it "passes the string through to the select clause" do
- Projection.new(@relation, @string).to_sql.should be_like("
+ Projection.new(@relation, 'asdf').to_sql.should be_like("
SELECT asdf FROM `users`
")
end
end
end
+
+ describe Projection::Externalizable do
+ describe '#aggregation?' do
+ describe 'when the projections are attributes' do
+ it 'returns false' do
+ Projection.new(@relation, @attribute).should_not be_aggregation
+ end
+ end
+
+ describe 'when the projections include an aggregation' do
+ it "obtains" do
+ Projection.new(@relation, @attribute.sum).should be_aggregation
+ end
+ end
+ end
+
+ end
end
end \ No newline at end of file
diff --git a/spec/active_relation/unit/relations/relation_spec.rb b/spec/active_relation/unit/relations/relation_spec.rb
index 2b62c8db5e..c40974e136 100644
--- a/spec/active_relation/unit/relations/relation_spec.rb
+++ b/spec/active_relation/unit/relations/relation_spec.rb
@@ -154,18 +154,15 @@ module ActiveRelation
end
end
- describe '#aggregate' do
- before do
- @expression1 = @attribute1.sum
- @expression2 = @attribute2.sum
+ describe '#group' do
+ it 'manufactures a group relation' do
+ @relation.group(@attribute1, @attribute2).should == Grouping.new(@relation, @attribute1, @attribute2)
end
- it 'manufactures a group relation' do
- @relation.aggregate(@expression1, @expression2).group(@attribute1, @attribute2). \
- should == Aggregation.new(@relation,
- :expressions => [@expression1, @expression2],
- :groupings => [@attribute1, @attribute2]
- )
+ describe 'when given blank groupings' do
+ it 'returns self' do
+ @relation.group.should == @relation
+ end
end
end