From 8edfa8f82fecb23af506278d510ea900e6021e6b Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Sun, 3 Jan 2010 18:57:57 +0530 Subject: Move Relation#spawn and Relation#merge to a separate module --- activerecord/lib/active_record.rb | 1 + activerecord/lib/active_record/relation.rb | 47 +-------------------- .../lib/active_record/relation/spawn_methods.rb | 49 ++++++++++++++++++++++ 3 files changed, 51 insertions(+), 46 deletions(-) create mode 100644 activerecord/lib/active_record/relation/spawn_methods.rb (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index cf439b0dc0..728dec8925 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -55,6 +55,7 @@ module ActiveRecord autoload :FinderMethods autoload :CalculationMethods autoload :PredicateBuilder + autoload :SpawnMethods end autoload :Base diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 9cfd9b6d23..a4d11f813d 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -1,6 +1,6 @@ module ActiveRecord class Relation - include QueryMethods, FinderMethods, CalculationMethods + include QueryMethods, FinderMethods, CalculationMethods, SpawnMethods delegate :length, :collect, :map, :each, :all?, :to => :to_a @@ -28,41 +28,6 @@ module ActiveRecord with_create_scope { @klass.create!(*args, &block) } 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) return true if @relation.respond_to?(method, include_private) || Array.method_defined?(method) @@ -164,16 +129,6 @@ module ActiveRecord self 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 @table ||= Arel::Table.new(@klass.table_name, Arel::Sql::Engine.new(@klass)) end diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb new file mode 100644 index 0000000000..4a64f0c6a9 --- /dev/null +++ b/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 -- cgit v1.2.3