aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation/spawn_methods.rb
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2010-01-03 18:57:57 +0530
committerPratik Naik <pratiknaik@gmail.com>2010-01-03 18:57:57 +0530
commit8edfa8f82fecb23af506278d510ea900e6021e6b (patch)
treed15e65c54ce0f4bcbec866fa4764bd235ce302aa /activerecord/lib/active_record/relation/spawn_methods.rb
parent3eca0ab8388a84bf34a78395edf85e30c6943c63 (diff)
downloadrails-8edfa8f82fecb23af506278d510ea900e6021e6b.tar.gz
rails-8edfa8f82fecb23af506278d510ea900e6021e6b.tar.bz2
rails-8edfa8f82fecb23af506278d510ea900e6021e6b.zip
Move Relation#spawn and Relation#merge to a separate module
Diffstat (limited to 'activerecord/lib/active_record/relation/spawn_methods.rb')
-rw-r--r--activerecord/lib/active_record/relation/spawn_methods.rb49
1 files changed, 49 insertions, 0 deletions
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