summaryrefslogtreecommitdiffstats
path: root/lib/puppet/util
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/util')
-rw-r--r--lib/puppet/util/rails/collection_merger.rb43
1 files changed, 30 insertions, 13 deletions
diff --git a/lib/puppet/util/rails/collection_merger.rb b/lib/puppet/util/rails/collection_merger.rb
index 7afd76f9c..69e0309c9 100644
--- a/lib/puppet/util/rails/collection_merger.rb
+++ b/lib/puppet/util/rails/collection_merger.rb
@@ -1,24 +1,41 @@
module Puppet::Util::CollectionMerger
# Merge new values with the old list. This is only necessary
# because deletion seems to mess things up on unsaved objects.
- def collection_merge(collection, list)
- remove = send(collection).dup
-
- list.each do |value|
- object = yield(value)
- if remove.include?(object)
- remove.delete(object)
+ def collection_merge(collection, args)
+ remove = []
+ list = args[:existing] || send(collection)
+ hash = args[:updates]
+ list.each do |object|
+ name = object.name
+ if existing = hash[name]
+ hash.delete(name)
+ if existing.respond_to?(:to_rails)
+ existing.to_rails(self, object)
+ elsif args.include?(:modify)
+ args[:modify].call(object, name, existing)
+ else
+ raise ArgumentError, "Must pass :modify or the new objects must respond to :to_rails"
+ end
+ else
+ remove << object
end
end
- unless remove.empty?
- # We have to save the current state else the deletion somehow deletes
- # our new values.
- save
- remove.each do |r|
- send(collection).delete(r)
+ # Make a new rails object for the rest of them
+ hash.each do |name, object|
+ if object.respond_to?(:to_rails)
+ object.to_rails(self)
+ elsif args.include?(:create)
+ args[:create].call(name, object)
+ else
+ raise ArgumentError, "Must pass :create or the new objects must respond to :to_rails"
end
end
+
+ # Now remove anything necessary.
+ remove.each do |object|
+ send(collection).delete(object)
+ end
end
end