diff options
Diffstat (limited to 'activerecord/lib/active_record/relation/merger.rb')
-rw-r--r-- | activerecord/lib/active_record/relation/merger.rb | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/activerecord/lib/active_record/relation/merger.rb b/activerecord/lib/active_record/relation/merger.rb index 1c2a06328f..3f880ce5e9 100644 --- a/activerecord/lib/active_record/relation/merger.rb +++ b/activerecord/lib/active_record/relation/merger.rb @@ -3,32 +3,41 @@ require 'active_support/core_ext/hash/keys' module ActiveRecord class Relation - class Merger - attr_reader :relation, :other + class HashMerger + attr_reader :relation, :hash - def initialize(relation, other) - @relation = relation + def initialize(relation, hash) + hash.assert_valid_keys(*Relation::VALUE_METHODS) - if other.default_scoped? && other.klass != relation.klass - @other = other.with_default_scope - else - @other = other - end + @relation = relation + @hash = hash end def merge - HashMerger.new(relation, other.values).merge + Merger.new(relation, other).merge + end + + # Applying values to a relation has some side effects. E.g. + # interpolation might take place for where values. So we should + # build a relation to merge in rather than directly merging + # the values. + def other + other = Relation.new(relation.klass, relation.table) + hash.each { |k, v| other.send("#{k}!", v) } + other end end - class HashMerger + class Merger attr_reader :relation, :values - def initialize(relation, values) - values.assert_valid_keys(*Relation::VALUE_METHODS) + def initialize(relation, other) + if other.default_scoped? && other.klass != relation.klass + other = other.with_default_scope + end @relation = relation - @values = values + @values = other.values end def normal_values |