+ private
+
+ def save_with_history!
+ t = Time.now.utc
+
+ self.version += 1
+ self.timestamp = t
+
+ # update the bounding box, note that this has to be done both before
+ # and after the save, so that nodes from both versions are included in the
+ # bbox. we use a copy of the changeset so that it isn't reloaded
+ # later in the save.
+ cs = changeset
+ cs.update_bbox!(bbox) unless nodes.empty?
+
+ Way.transaction do
+ # clone the object before saving it so that the original is
+ # still marked as dirty if we retry the transaction
+ clone.save!
+
+ tags = self.tags
+ WayTag.where(:way_id => id).delete_all
+ tags.each do |k, v|
+ tag = WayTag.new
+ tag.way_id = id
+ tag.k = k
+ tag.v = v
+ tag.save!
+ end
+
+ nds = self.nds
+ WayNode.where(:way_id => id).delete_all
+ sequence = 1
+ nds.each do |n|
+ nd = WayNode.new
+ nd.id = [id, sequence]
+ nd.node_id = n
+ nd.save!
+ sequence += 1
+ end
+
+ old_way = OldWay.from_way(self)
+ old_way.timestamp = t
+ old_way.save_with_dependencies!
+
+ # reload the way so that the nodes array points to the correct
+ # new set of nodes.
+ reload
+
+ # update and commit the bounding box, now that way nodes
+ # have been updated and we're in a transaction.
+ cs.update_bbox!(bbox) unless nodes.empty?
+
+ # tell the changeset we updated one element only
+ cs.add_changes! 1
+
+ cs.save!
+ end
+ end