diff options
| -rw-r--r-- | activerecord/lib/active_record.rb | 1 | ||||
| -rw-r--r-- | activerecord/lib/active_record/relation.rb | 47 | ||||
| -rw-r--r-- | activerecord/lib/active_record/relation/spawn_methods.rb | 49 | 
3 files changed, 51 insertions, 46 deletions
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  | 
