module Fiona7 class ReleaseController < ActionController::Base def release @releasable = Set.new @errors = [] @obj = WriteObj.find(params[:id]) recursively_find_objects(@releasable, @obj, Set.new) @releasable.each do |obj| if obj.really_edited? carefully_release(@errors, obj) end end # TODO: display errors render json: {} end protected def carefully_release(errors, obj) obj.take obj.release! rescue => e Rails.logger.error("Error occured when releasing #{@obj.id}: unable to release Object with ID #{obj.id} (#{obj.path} because: #{e.inspect}") # TODO: translate error = "Unable to release Object with ID #{obj.id} because: #{e.message}" errors << error end def recursively_find_objects(set, obj, already_encountered) # already_encountered prevents loops widgets_of_this_object = widgets(obj) - already_encountered referenced_objects_of_this_object = referenced_objects(obj) - already_encountered already_encountered.merge(widgets_of_this_object) already_encountered.merge(referenced_objects_from_widgets) widgets_of_this_object.each do |widget| recursively_find_objects(set, widget, already_encountered) end referenced_objects_of_this_object.each do |referenced| recursively_find_objects(set, referenced, already_encountered) end set.merge(widgets_of_this_object) set.merge(referenced_objects_of_this_object) set << obj set end def widgets(obj) links = @obj[:X_widget_pool] || [] WriteObj.where(obj_id: links.map {|l| l.destination_object_id }).to_a.to_set end def referenced_objects(obj) referenced = Set.new type_definition = Fiona7::TypeRegister.instance.read_mangled(obj.obj_class) type_definition.attributes.each do |attribute| if attribute.type == :reference || attribute.type == :referencelist (obj[attribute.real_name] || []).each do |link| if link.internal? referenced << link.destination_object end end end end referenced end end end