aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/lib/active_record/relation/merger.rb81
1 files changed, 45 insertions, 36 deletions
diff --git a/activerecord/lib/active_record/relation/merger.rb b/activerecord/lib/active_record/relation/merger.rb
index 2f50b9a492..3541645e1d 100644
--- a/activerecord/lib/active_record/relation/merger.rb
+++ b/activerecord/lib/active_record/relation/merger.rb
@@ -14,7 +14,18 @@ module ActiveRecord
end
def merge
- Relation::ASSOCIATION_METHODS.each do |method|
+ merge_multi_values
+ merge_single_values
+
+ relation
+ end
+
+ private
+
+ def merge_multi_values
+ values = Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS - [:where, :order, :bind]
+
+ values.each do |method|
value = other.send(:"#{method}_values")
unless value.empty?
@@ -22,19 +33,43 @@ module ActiveRecord
end
end
- (Relation::MULTI_VALUE_METHODS - [:joins, :where, :order, :binds]).each do |method|
- value = other.send(:"#{method}_values")
- next if value.empty?
+ relation.where_values = merged_wheres
+ relation.bind_values = merged_binds
- value += relation.send(:"#{method}_values")
- relation.send :"#{method}_values=", value
+ if other.reordering_value
+ # override any order specified in the original relation
+ relation.reorder! other.order_values
+ else
+ # merge in order_values from r
+ relation.order_values += other.order_values
end
- relation.joins_values += other.joins_values
+ # Apply scope extension modules
+ relation.send :apply_modules, other.extensions
+ end
- merged_wheres = relation.where_values + other.where_values
+ def merge_single_values
+ values = Relation::SINGLE_VALUE_METHODS - [:reverse_order, :lock, :create_with, :reordering]
+
+ values.each do |method|
+ value = other.send(:"#{method}_value")
+ relation.send("#{method}!", value) if value
+ end
+
+ relation.lock_value = other.lock_value unless relation.lock_value
+ relation.reverse_order_value = other.reverse_order_value
+
+ unless other.create_with_value.empty?
+ relation.create_with_value = (relation.create_with_value || {}).merge(other.create_with_value)
+ end
+ end
+
+ def merged_binds
+ (relation.bind_values + other.bind_values).uniq(&:first)
+ end
- merged_binds = (relation.bind_values + other.bind_values).uniq(&:first)
+ def merged_wheres
+ merged_wheres = relation.where_values + other.where_values
unless relation.where_values.empty?
# Remove duplicates, last one wins.
@@ -51,33 +86,7 @@ module ActiveRecord
}.reverse
end
- relation.where_values = merged_wheres
- relation.bind_values = merged_binds
-
- (Relation::SINGLE_VALUE_METHODS - [:lock, :create_with, :reordering]).each do |method|
- value = other.send(:"#{method}_value")
- relation.send(:"#{method}_value=", value) unless value.nil?
- end
-
- relation.lock_value = other.lock_value unless relation.lock_value
-
- unless other.create_with_value.empty?
- relation.create_with_value = (relation.create_with_value || {}).merge(other.create_with_value)
- end
-
- if other.reordering_value
- # override any order specified in the original relation
- relation.reordering_value = true
- relation.order_values = other.order_values
- else
- # merge in order_values from r
- relation.order_values += other.order_values
- end
-
- # Apply scope extension modules
- relation.send :apply_modules, other.extensions
-
- relation
+ merged_wheres
end
end
end