mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
this is very messy but it is finally close to feature-complete
This commit is contained in:
parent
6c73e3dbc7
commit
b6c0de24fa
17 changed files with 180 additions and 105 deletions
|
@ -3,6 +3,10 @@ class Object
|
|||
self
|
||||
end
|
||||
|
||||
def substitute(relation)
|
||||
self
|
||||
end
|
||||
|
||||
def to_sql(strategy = ActiveRelation::Sql::Scalar.new)
|
||||
strategy.scalar self
|
||||
end
|
||||
|
|
|
@ -19,6 +19,10 @@ module ActiveRelation
|
|||
def qualify
|
||||
self.class.new(attribute.qualify, operand.qualify)
|
||||
end
|
||||
|
||||
def substitute(relation)
|
||||
self.class.new(attribute.substitute(relation), operand.substitute(relation))
|
||||
end
|
||||
|
||||
def to_sql(strategy = Sql::Predicate.new)
|
||||
"#{attribute.to_sql(strategy)} #{predicate_sql} #{operand.to_sql(strategy)}"
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
module ActiveRelation
|
||||
class Attribute
|
||||
attr_reader :relation, :name, :alias
|
||||
attr_reader :relation, :name, :alias, :ancestor
|
||||
|
||||
def initialize(relation, name, aliaz = nil)
|
||||
@relation, @name, @alias = relation, name, aliaz
|
||||
def initialize(relation, name, aliaz = nil, ancestor = nil)
|
||||
@relation, @name, @alias, @ancestor = relation, name, aliaz, ancestor
|
||||
end
|
||||
|
||||
module Transformations
|
||||
def as(aliaz = nil)
|
||||
Attribute.new(relation, name, aliaz)
|
||||
Attribute.new(relation, name, aliaz, self)
|
||||
end
|
||||
|
||||
def substitute(new_relation)
|
||||
Attribute.new(new_relation, name, @alias)
|
||||
relation == new_relation ? self : Attribute.new(new_relation, name, @alias, self)
|
||||
end
|
||||
|
||||
def qualify
|
||||
|
@ -26,11 +26,19 @@ module ActiveRelation
|
|||
include Transformations
|
||||
|
||||
def qualified_name
|
||||
"#{relation.name}.#{name}"
|
||||
"#{prefix}.#{name}"
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
self.class == other.class and relation == other.relation and name == other.name and @alias == other.alias
|
||||
self.class == other.class and relation == other.relation and name == other.name and @alias == other.alias and ancestor == other.ancestor
|
||||
end
|
||||
|
||||
def =~(other)
|
||||
!(history & other.history).empty?
|
||||
end
|
||||
|
||||
def history
|
||||
[self] + (ancestor ? [ancestor, ancestor.history].flatten : [])
|
||||
end
|
||||
|
||||
module Predications
|
||||
|
@ -84,7 +92,12 @@ module ActiveRelation
|
|||
include Expressions
|
||||
|
||||
def to_sql(strategy = Sql::Predicate.new)
|
||||
strategy.attribute relation.name, name, self.alias
|
||||
strategy.attribute prefix, name, self.alias
|
||||
end
|
||||
|
||||
private
|
||||
def prefix
|
||||
relation.prefix_for(self)
|
||||
end
|
||||
end
|
||||
end
|
50
lib/active_relation/primitives/expression.rb
Normal file
50
lib/active_relation/primitives/expression.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
module ActiveRelation
|
||||
class Expression
|
||||
include Sql::Quoting
|
||||
|
||||
attr_reader :attribute, :function_sql, :alias, :ancestor
|
||||
delegate :relation, :to => :attribute
|
||||
|
||||
def initialize(attribute, function_sql, aliaz = nil, ancestor = nil)
|
||||
@attribute, @function_sql, @alias, @ancestor = attribute, function_sql, aliaz, ancestor
|
||||
end
|
||||
|
||||
module Transformations
|
||||
def substitute(new_relation)
|
||||
Expression.new(attribute.substitute(new_relation), function_sql, @alias, self)
|
||||
end
|
||||
|
||||
def as(aliaz)
|
||||
# key line -- note self
|
||||
Expression.new(attribute, function_sql, aliaz, self)
|
||||
end
|
||||
|
||||
def to_attribute
|
||||
# key line -- note self
|
||||
Attribute.new(relation, @alias, nil, self)
|
||||
end
|
||||
end
|
||||
include Transformations
|
||||
|
||||
def to_sql(strategy = nil)
|
||||
"#{function_sql}(#{attribute.to_sql})" + (@alias ? " AS #{quote_column_name(@alias)}" : '')
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
self.class == other.class and attribute == other.attribute and function_sql == other.function_sql and ancestor == other.ancestor and @alias == other.alias
|
||||
end
|
||||
alias_method :eql?, :==
|
||||
|
||||
def hash
|
||||
attribute.hash + function_sql.hash
|
||||
end
|
||||
|
||||
def =~(other)
|
||||
!(history & other.history).empty?
|
||||
end
|
||||
|
||||
def history
|
||||
[self] + (ancestor ? [ancestor, ancestor.history].flatten : [])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,27 +1,26 @@
|
|||
module ActiveRelation
|
||||
class Aggregation < Compound
|
||||
attr_reader :expressions, :groupings
|
||||
alias_method :attributes, :expressions
|
||||
|
||||
def initialize(relation, options)
|
||||
@relation, @expressions, @groupings = relation, options[:expressions], options[:groupings]
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
relation == other.relation and groupings == other.groupings and expressions == other.expressions
|
||||
self.class == other.class and relation == other.relation and groupings == other.groupings and expressions == other.expressions
|
||||
end
|
||||
|
||||
def qualify
|
||||
Aggregation.new(relation.qualify, :expressions => expressions.collect(&:qualify), :groupings => groupings.collect(&:qualify))
|
||||
end
|
||||
|
||||
def attributes
|
||||
expressions.collect { |e| e.substitute(self) }
|
||||
end
|
||||
|
||||
protected
|
||||
def aggregation?
|
||||
true
|
||||
end
|
||||
|
||||
def attribute_for_expression(expression)
|
||||
expression.relation == self ? expression : (e = @expressions.detect { |e| e == expression }) && e.substitute(self)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,13 +1,17 @@
|
|||
module ActiveRelation
|
||||
class Alias < Compound
|
||||
attr_reader :alias
|
||||
|
||||
def aliased_prefix_for(attribute)
|
||||
@alias
|
||||
end
|
||||
|
||||
def initialize(relation, aliaz)
|
||||
@relation, @alias = relation, aliaz
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
relation == other.relation and @alias == other.alias
|
||||
self.class == other.class and relation == other.relation and @alias == other.alias
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,7 +2,7 @@ module ActiveRelation
|
|||
class Compound < Relation
|
||||
attr_reader :relation
|
||||
delegate :joins, :selects, :orders, :groupings, :table_sql, :inserts, :limit,
|
||||
:offset, :name, :alias, :aggregation?,
|
||||
:offset, :name, :alias, :aggregation?, :prefix_for, :aliased_prefix_for,
|
||||
:to => :relation
|
||||
|
||||
def attributes
|
||||
|
@ -11,15 +11,7 @@ module ActiveRelation
|
|||
|
||||
protected
|
||||
def attribute_for_name(name)
|
||||
(a = relation[name]) && a.substitute(self)
|
||||
end
|
||||
|
||||
def attribute_for_attribute(attribute)
|
||||
attribute.relation == self ? attribute : (a = relation[attribute]) && a.substitute(self)
|
||||
end
|
||||
|
||||
def attribute_for_expression(expression)
|
||||
expression.relation == self ? expression : (a = relation[expression]) && a.substitute(self)
|
||||
relation[name].substitute(self) rescue nil
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,7 +7,8 @@ module ActiveRelation
|
|||
end
|
||||
|
||||
def ==(other)
|
||||
predicates == other.predicates and
|
||||
self.class == other.class and
|
||||
predicates == other.predicates and
|
||||
((relation1 == other.relation1 and relation2 == other.relation2) or
|
||||
(relation2 == other.relation1 and relation1 == other.relation2))
|
||||
end
|
||||
|
@ -20,8 +21,15 @@ module ActiveRelation
|
|||
[
|
||||
relation1.aggregation?? relation1.attributes.collect(&:to_attribute) : relation1.attributes,
|
||||
relation2.aggregation?? relation2.attributes.collect(&:to_attribute) : relation2.attributes,
|
||||
].flatten
|
||||
].flatten.collect { |a| a.substitute(self) }
|
||||
end
|
||||
|
||||
def prefix_for(attribute)
|
||||
# test me
|
||||
(relation1[attribute] && relation1.aliased_prefix_for(attribute)) ||
|
||||
(relation2[attribute] && relation2.aliased_prefix_for(attribute))
|
||||
end
|
||||
alias_method :aliased_prefix_for, :prefix_for
|
||||
|
||||
protected
|
||||
def joins
|
||||
|
@ -36,11 +44,11 @@ module ActiveRelation
|
|||
end
|
||||
|
||||
def attribute_for_name(name)
|
||||
relation1[name] || relation2[name]
|
||||
(relation1[name] || relation2[name])
|
||||
end
|
||||
|
||||
def attribute_for_attribute(attribute)
|
||||
relation1[attribute] || relation2[attribute]
|
||||
(relation1[attribute] || relation2[attribute])
|
||||
end
|
||||
|
||||
def table_sql
|
||||
|
@ -49,7 +57,7 @@ module ActiveRelation
|
|||
|
||||
private
|
||||
def join
|
||||
[join_sql, right_table_sql, "ON", predicates.collect { |p| p.to_sql(Sql::Predicate.new) }.join(' AND ')].join(" ")
|
||||
[join_sql, right_table_sql, "ON", predicates.collect { |p| p.substitute(self).to_sql(Sql::Predicate.new) }.join(' AND ')].join(" ")
|
||||
end
|
||||
|
||||
def right_table_sql
|
||||
|
|
|
@ -30,10 +30,8 @@ module ActiveRelation
|
|||
attribute_for_name(index)
|
||||
when ::Range
|
||||
Range.new(self, index)
|
||||
when Attribute
|
||||
when Attribute, Expression
|
||||
attribute_for_attribute(index)
|
||||
when Expression
|
||||
attribute_for_expression(index)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -110,12 +108,12 @@ module ActiveRelation
|
|||
ActiveRecord::Base.connection
|
||||
end
|
||||
|
||||
def attribute_for_attribute(attribute)
|
||||
self == attribute.relation ? attribute : nil
|
||||
def attribute_for_name(name)
|
||||
nil
|
||||
end
|
||||
|
||||
def attribute_for_expression(expression)
|
||||
nil
|
||||
def attribute_for_attribute(attribute)
|
||||
attributes.detect { |a| a =~ attribute }
|
||||
end
|
||||
|
||||
def attributes; [] end
|
||||
|
|
|
@ -23,22 +23,14 @@ module ActiveRelation
|
|||
def attribute_for_name(name)
|
||||
case
|
||||
when referring_by_autonym?(name) then nil
|
||||
when referring_by_pseudonym?(name) then attribute.as(pseudonym).substitute(self)
|
||||
else (a = relation[name]) && a.substitute(self)
|
||||
when referring_by_pseudonym?(name) then substitute(relation[attribute])
|
||||
else relation[name].substitute(self) rescue nil
|
||||
end
|
||||
end
|
||||
|
||||
def attribute_for_attribute(attribute)
|
||||
attribute.relation == self ? attribute : substitute(relation[attribute])
|
||||
end
|
||||
|
||||
def attribute_for_expression(expression)
|
||||
expression.relation == self ? expression : substitute(relation[expression])
|
||||
end
|
||||
|
||||
private
|
||||
def substitute(attribute)
|
||||
(relation[attribute] == relation[self.attribute] ? attribute.as(pseudonym) : attribute).substitute(self) if attribute
|
||||
(attribute =~ self.attribute ? attribute.as(pseudonym) : attribute).substitute(self) rescue nil
|
||||
end
|
||||
|
||||
def referring_by_autonym?(name)
|
||||
|
|
|
@ -8,7 +8,7 @@ module ActiveRelation
|
|||
end
|
||||
|
||||
def ==(other)
|
||||
relation == other.relation and predicate == other.predicate
|
||||
self.class == other.class and relation == other.relation and predicate == other.predicate
|
||||
end
|
||||
|
||||
def qualify
|
||||
|
|
|
@ -14,15 +14,19 @@ module ActiveRelation
|
|||
Rename.new self, qualifications
|
||||
end
|
||||
|
||||
def inspect
|
||||
"<Table: #{name}>"
|
||||
def prefix_for(attribute)
|
||||
name
|
||||
end
|
||||
|
||||
|
||||
def aliased_prefix_for(attribute)
|
||||
name
|
||||
end
|
||||
|
||||
protected
|
||||
def attribute_for_name(name)
|
||||
attributes_by_name[name.to_s]
|
||||
end
|
||||
|
||||
|
||||
def table_sql
|
||||
"#{quote_table_name(name)}"
|
||||
end
|
||||
|
|
|
@ -14,19 +14,19 @@ module ActiveRelation
|
|||
|
||||
describe '#as' do
|
||||
it "manufactures an aliased attributed" do
|
||||
@attribute.as(:alias).should == Attribute.new(@relation1, @attribute.name, :alias)
|
||||
@attribute.as(:alias).should == Attribute.new(@relation1, @attribute.name, :alias, @attribute)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#substitute' do
|
||||
it "manufactures an attribute with the relation substituted" do
|
||||
@attribute.substitute(@relation2).should == Attribute.new(@relation2, @attribute.name)
|
||||
@attribute.substitute(@relation2).should == Attribute.new(@relation2, @attribute.name, nil, @attribute)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#qualify' do
|
||||
it "manufactures an attribute aliased with that attributes qualified name" do
|
||||
@attribute.qualify.should == Attribute.new(@attribute.relation, @attribute.name, @attribute.qualified_name)
|
||||
@attribute.qualify.should == Attribute.new(@attribute.relation, @attribute.name, @attribute.qualified_name, @attribute)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -53,6 +53,10 @@ module ActiveRelation
|
|||
end
|
||||
|
||||
describe '#to_sql' do
|
||||
it "needs to test prefix_for" do
|
||||
pending
|
||||
end
|
||||
|
||||
describe Sql::Strategy do
|
||||
it "manufactures sql without an alias if the strategy is Predicate" do
|
||||
Attribute.new(@relation1, :name, :alias).to_sql(Sql::Predicate.new).should be_like("`foo`.`name`")
|
||||
|
@ -62,19 +66,6 @@ module ActiveRelation
|
|||
Attribute.new(@relation1, :name, :alias).to_sql(Sql::Projection.new).should be_like("`foo`.`name` AS 'alias'")
|
||||
end
|
||||
end
|
||||
|
||||
describe 'binding' do
|
||||
before do
|
||||
@attribute = Attribute.new(@relation1, :name, :alias)
|
||||
@aliased_relation = @relation1.as(:schmoo)
|
||||
end
|
||||
|
||||
it "is fancy pants" do
|
||||
pending
|
||||
@attribute.to_sql.should be_like("`foo`.`name`")
|
||||
@attribute.substitute(@aliased_relation).to_sql.should be_like("`schmoo`.`alias`")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe Attribute::Predications do
|
||||
|
@ -120,7 +111,7 @@ module ActiveRelation
|
|||
end
|
||||
end
|
||||
|
||||
describe 'Expressions' do
|
||||
describe Attribute::Expressions do
|
||||
before do
|
||||
@attribute1 = Attribute.new(@relation1, :name)
|
||||
end
|
||||
|
|
|
@ -14,35 +14,36 @@ module ActiveRelation
|
|||
|
||||
describe '#attributes' do
|
||||
it 'manufactures attributes associated with the compound relation' do
|
||||
@compound_relation.attributes.should == @relation.attributes.collect { |a| Attribute.new(@compound_relation, a.name) }
|
||||
@compound_relation.attributes.should == @relation.attributes.collect { |a| a.substitute(@compound_relation) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '[]' do
|
||||
describe 'when given a', Symbol do
|
||||
it 'manufactures attributes associated with the compound relation if the symbol names an attribute within the relation' do
|
||||
@compound_relation[:id].relation.should == @compound_relation
|
||||
@compound_relation[:id].should == @relation[:id].substitute(@compound_relation)
|
||||
@compound_relation[:does_not_exist].should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when given an', Attribute do
|
||||
it "manufactures a substituted attribute when given an attribute within the relation" do
|
||||
@compound_relation[Attribute.new(@relation, :id)].should == Attribute.new(@compound_relation, :id)
|
||||
@compound_relation[Attribute.new(@compound_relation, :id)].should == Attribute.new(@compound_relation, :id)
|
||||
@compound_relation[Attribute.new(another_relation = Table.new(:photos), :id)].should be_nil
|
||||
@compound_relation[@relation[:id]].should == @relation[:id].substitute(@compound_relation)
|
||||
@compound_relation[@compound_relation[:id]].should == @compound_relation[:id]
|
||||
pending "test nil"
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when given an', Expression do
|
||||
before do
|
||||
@nested_expression = Expression.new(Attribute.new(@relation, :id), "COUNT")
|
||||
@nested_relation = Aggregation.new(@relation, :expressions => [@nested_expression])
|
||||
@unprojected_expression = Expression.new(Attribute.new(@relation, :id), "SUM")
|
||||
@compound_relation = ConcreteCompound.new(Aggregation.new(@relation, :expressions => [@nested_expression]))
|
||||
@compound_relation = ConcreteCompound.new(@nested_relation)
|
||||
end
|
||||
|
||||
it "manufactures a substituted Expression when given an Expression within the relation" do
|
||||
@compound_relation[@nested_expression].should == @nested_expression.substitute(@compound_relation)
|
||||
@compound_relation[@nested_expression].should == @nested_relation[@nested_expression].substitute(@compound_relation)
|
||||
@compound_relation[@compound_relation[@expression]].should == @compound_relation[@expression]
|
||||
@compound_relation[@unprojected_expression].should be_nil
|
||||
end
|
||||
|
|
|
@ -34,9 +34,13 @@ module ActiveRelation
|
|||
|
||||
describe '#attributes' do
|
||||
describe 'with simple relations' do
|
||||
before do
|
||||
@join = Join.new("INNER JOIN", @relation1, @relation2, @predicate)
|
||||
end
|
||||
|
||||
it 'combines the attributes of the two relations' do
|
||||
Join.new("INNER JOIN", @relation1, @relation2, @predicate).attributes.should ==
|
||||
@relation1.attributes + @relation2.attributes
|
||||
@join.attributes.should ==
|
||||
(@relation1.attributes + @relation2.attributes).collect { |a| a.substitute(@join) }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -73,8 +77,8 @@ module ActiveRelation
|
|||
before do
|
||||
@relation = Table.new(:users)
|
||||
photos = Table.new(:photos)
|
||||
@aggregate_relation = photos.aggregate(photos[:user_id], photos[:id].count).group(photos[:user_id]).rename(photos[:id].count, :cnt) \
|
||||
.as(:photo_count)
|
||||
aggregate_relation = photos.aggregate(photos[:user_id], photos[:id].count).group(photos[:user_id])
|
||||
@aggregate_relation = aggregate_relation.rename(photos[:id].count, :cnt).as(:photo_count)
|
||||
@predicate = Equality.new(@aggregate_relation[:user_id], @relation[:id])
|
||||
end
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ module ActiveRelation
|
|||
|
||||
describe '#attributes' do
|
||||
it "manufactures a list of attributes with the renamed attribute renameed" do
|
||||
@renamed_relation.attributes.should include(Attribute.new(@renamed_relation, :id, :schmid))
|
||||
@renamed_relation.attributes.should include(@renamed_relation[:schmid])
|
||||
@renamed_relation.should have(@relation1.attributes.size).attributes
|
||||
end
|
||||
end
|
||||
|
@ -34,17 +34,17 @@ module ActiveRelation
|
|||
describe 'when given a', Symbol do
|
||||
it 'indexes attributes by rename if the symbol names an attribute within the relation' do
|
||||
@renamed_relation[:id].should be_nil
|
||||
@renamed_relation[:schmid].should == Attribute.new(@renamed_relation, :id, :schmid)
|
||||
@renamed_relation[:schmid].should == @relation1[:id].as(:schmid).substitute(@renamed_relation)
|
||||
@renamed_relation[:does_not_exist].should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when given an', Attribute do
|
||||
it 'manufactures a substituted and renamed attribute if the attribute is within the relation' do
|
||||
@renamed_relation[Attribute.new(@relation1, :id)].should == Attribute.new(@renamed_relation, :id, :schmid)
|
||||
@renamed_relation[Attribute.new(@relation1, :name)].should == Attribute.new(@renamed_relation, :name)
|
||||
@renamed_relation[Attribute.new(@renamed_relation, :name)].should == Attribute.new(@renamed_relation, :name)
|
||||
@renamed_relation[Attribute.new(@relation2, :id)].should be_nil
|
||||
@renamed_relation[@relation1[:id]].should == @relation1[:id].as(:schmid).substitute(@renamed_relation)
|
||||
@renamed_relation[@relation1[:name]].should == @relation1[:name].substitute(@renamed_relation)
|
||||
@renamed_relation[@renamed_relation[:name]].should == @renamed_relation[:name]
|
||||
@renamed_relation[@relation2[:id]].should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -62,22 +62,26 @@ module ActiveRelation
|
|||
it 'manufactures a substituted and renamed attribute if the attribute is within the relation' do
|
||||
@renamed_renamed_relation[:id].should be_nil
|
||||
@renamed_renamed_relation[:schmid].should be_nil
|
||||
@renamed_renamed_relation[:flid].should == Attribute.new(@renamed_renamed_relation, :id, :flid)
|
||||
@renamed_renamed_relation[:flid].should == @renamed_relation[:schmid].as(:flid).substitute(@renamed_renamed_relation)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when given an', Attribute do
|
||||
it "manufactures a substituted and renamed attribute if the attribute is within the relation -- even if the provided attribute derived" do
|
||||
@renamed_renamed_relation[Attribute.new(@renamed_relation, :id, :schmid)].should == Attribute.new(@renamed_renamed_relation, :id, :flid)
|
||||
@renamed_renamed_relation[Attribute.new(@relation1, :id)].should == Attribute.new(@renamed_renamed_relation, :id, :flid)
|
||||
@renamed_renamed_relation[@renamed_relation[:schmid]].should == @renamed_relation[:schmid].as(:flid).substitute(@renamed_renamed_relation)
|
||||
@renamed_renamed_relation[@relation1[:id]].should == @renamed_relation[:schmid].as(:flid).substitute(@renamed_renamed_relation)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when given an', Expression do
|
||||
before do
|
||||
@expression = @relation1[:id].count
|
||||
@aggregation = Aggregation.new(@relation1, :expressions => [@expression])
|
||||
@renamed_relation = Rename.new(@aggregation, @expression => :cnt)
|
||||
end
|
||||
|
||||
it "manufactures a substituted and renamed expression if the expression is within the relation" do
|
||||
renamed_relation = Rename.new(Aggregation.new(@relation1, :expressions => [@relation1[:id].count]), @relation1[:id].count => :cnt)
|
||||
renamed_relation[@relation1[:id].count].should == @relation1[:id].count.as(:cnt).substitute(renamed_relation)
|
||||
renamed_relation.attributes.should == [@relation1[:id].count.as(:cnt).substitute(renamed_relation)]
|
||||
@renamed_relation[@expression].should == @aggregation[@expression].as(:cnt).substitute(@renamed_relation)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,56 +3,63 @@ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
|||
module ActiveRelation
|
||||
describe Table do
|
||||
before do
|
||||
@relation = Table.new(:users)
|
||||
@relation1 = Table.new(:users)
|
||||
@relation2 = Table.new(:photos)
|
||||
end
|
||||
|
||||
describe '[]' do
|
||||
describe 'when given a', Symbol do
|
||||
it "manufactures an attribute if the symbol names an attribute within the relation" do
|
||||
@relation[:id].should == Attribute.new(@relation, :id)
|
||||
@relation[:does_not_exist].should be_nil
|
||||
@relation1[:id].should == Attribute.new(@relation1, :id)
|
||||
@relation1[:does_not_exist].should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when given an', Attribute do
|
||||
it "returns the attribute if the attribute is within the relation" do
|
||||
@relation[Attribute.new(@relation, :id)].should == Attribute.new(@relation, :id)
|
||||
@relation[Attribute.new(another_relation = Table.new(:photos), :id)].should be_nil
|
||||
@relation1[@relation1[:id]].should == @relation1[:id]
|
||||
@relation1[@relation2[:id]].should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when given an', Expression do
|
||||
before do
|
||||
@expression = Expression.new(Attribute.new(@relation, :id), "COUNT")
|
||||
@expression = Expression.new(Attribute.new(@relation1, :id), "COUNT")
|
||||
end
|
||||
|
||||
it "returns the Expression if the Expression is within the relation" do
|
||||
@relation[@expression].should be_nil
|
||||
@relation1[@expression].should be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_sql' do
|
||||
it "manufactures a simple select query" do
|
||||
@relation.to_sql.should be_like("""
|
||||
@relation1.to_sql.should be_like("""
|
||||
SELECT `users`.`name`, `users`.`id`
|
||||
FROM `users`
|
||||
""")
|
||||
end
|
||||
end
|
||||
|
||||
describe '#prefix_for' do
|
||||
it "always returns the table name" do
|
||||
@relation1.prefix_for(Attribute.new(@relation1, :id)).should == :users
|
||||
end
|
||||
end
|
||||
|
||||
describe '#attributes' do
|
||||
it 'manufactures attributes corresponding to columns in the table' do
|
||||
@relation.attributes.should == [
|
||||
Attribute.new(@relation, :name),
|
||||
Attribute.new(@relation, :id)
|
||||
@relation1.attributes.should == [
|
||||
Attribute.new(@relation1, :name),
|
||||
Attribute.new(@relation1, :id)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe '#qualify' do
|
||||
it 'manufactures a rename relation with all attribute names qualified' do
|
||||
@relation.qualify.should == Rename.new(@relation, @relation[:id] => 'users.id', @relation[:name] => 'users.name')
|
||||
@relation1.qualify.should == Rename.new(@relation1, @relation1[:id] => 'users.id', @relation1[:name] => 'users.name')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue