Skip to content

Commit

Permalink
Move Relation#spawn and Relation#merge to a separate module
Browse files Browse the repository at this point in the history
  • Loading branch information
lifo committed Jan 3, 2010
1 parent 3eca0ab commit 8edfa8f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 46 deletions.
1 change: 1 addition & 0 deletions activerecord/lib/active_record.rb
Expand Up @@ -55,6 +55,7 @@ module ActiveRecord
autoload :FinderMethods autoload :FinderMethods
autoload :CalculationMethods autoload :CalculationMethods
autoload :PredicateBuilder autoload :PredicateBuilder
autoload :SpawnMethods
end end


autoload :Base autoload :Base
Expand Down
47 changes: 1 addition & 46 deletions activerecord/lib/active_record/relation.rb
@@ -1,6 +1,6 @@
module ActiveRecord module ActiveRecord
class Relation class Relation
include QueryMethods, FinderMethods, CalculationMethods include QueryMethods, FinderMethods, CalculationMethods, SpawnMethods


delegate :length, :collect, :map, :each, :all?, :to => :to_a delegate :length, :collect, :map, :each, :all?, :to => :to_a


Expand Down Expand Up @@ -28,41 +28,6 @@ def create!(*args, &block)
with_create_scope { @klass.create!(*args, &block) } with_create_scope { @klass.create!(*args, &block) }
end end


def merge(r)
raise ArgumentError, "Cannot merge a #{r.klass.name} relation with #{@klass.name} relation" if r.klass != @klass

merged_relation = spawn(table).eager_load(r.eager_load_associations).preload(r.preload_associations).includes(r.include_associations)
merged_relation.readonly = r.readonly

[self.relation, r.relation].each do |arel|
merged_relation = merged_relation.
joins(arel.joins(arel)).
group(arel.groupings).
limit(arel.taken).
offset(arel.skipped).
select(arel.send(:select_clauses)).
from(arel.sources)
end

relation_order = r.send(:order_clause)
merged_order = relation_order.present? ? relation_order : order_clause
merged_relation = merged_relation.order(merged_order)

merged_wheres = @relation.wheres

r.wheres.each do |w|
if w.is_a?(Arel::Predicates::Equality)
merged_wheres = merged_wheres.reject {|p| p.is_a?(Arel::Predicates::Equality) && p.operand1.name == w.operand1.name }
end

merged_wheres << w
end

merged_relation.where(*merged_wheres)
end

alias :& :merge

def respond_to?(method, include_private = false) def respond_to?(method, include_private = false)
return true if @relation.respond_to?(method, include_private) || Array.method_defined?(method) return true if @relation.respond_to?(method, include_private) || Array.method_defined?(method)


Expand Down Expand Up @@ -164,16 +129,6 @@ def reset
self self
end end


def spawn(relation = @relation)
relation = Relation.new(@klass, relation)
relation.readonly = @readonly
relation.preload_associations = @preload_associations
relation.eager_load_associations = @eager_load_associations
relation.include_associations = @include_associations
relation.table = table
relation
end

def table def table
@table ||= Arel::Table.new(@klass.table_name, Arel::Sql::Engine.new(@klass)) @table ||= Arel::Table.new(@klass.table_name, Arel::Sql::Engine.new(@klass))
end end
Expand Down
49 changes: 49 additions & 0 deletions activerecord/lib/active_record/relation/spawn_methods.rb
@@ -0,0 +1,49 @@
module ActiveRecord
module SpawnMethods
def spawn(relation = @relation)
relation = Relation.new(@klass, relation)
relation.readonly = @readonly
relation.preload_associations = @preload_associations
relation.eager_load_associations = @eager_load_associations
relation.include_associations = @include_associations
relation.table = table
relation
end

def merge(r)
raise ArgumentError, "Cannot merge a #{r.klass.name} relation with #{@klass.name} relation" if r.klass != @klass

merged_relation = spawn(table).eager_load(r.eager_load_associations).preload(r.preload_associations).includes(r.include_associations)
merged_relation.readonly = r.readonly

[self.relation, r.relation].each do |arel|
merged_relation = merged_relation.
joins(arel.joins(arel)).
group(arel.groupings).
limit(arel.taken).
offset(arel.skipped).
select(arel.send(:select_clauses)).
from(arel.sources)
end

relation_order = r.send(:order_clause)
merged_order = relation_order.present? ? relation_order : order_clause
merged_relation = merged_relation.order(merged_order)

merged_wheres = @relation.wheres

r.wheres.each do |w|
if w.is_a?(Arel::Predicates::Equality)
merged_wheres = merged_wheres.reject {|p| p.is_a?(Arel::Predicates::Equality) && p.operand1.name == w.operand1.name }
end

merged_wheres << w
end

merged_relation.where(*merged_wheres)
end

alias :& :merge

end
end

0 comments on commit 8edfa8f

Please sign in to comment.