Skip to content

Commit

Permalink
[Exports::CustomButtons] Refactor/Simplify
Browse files Browse the repository at this point in the history
The previous implementation of this exporter used very abstract logic to
export the specific data items needed.  While incredibly DRY as a
result, it is also very hard to parse and when the underlying DB
structure changes, it is even harder to fix (#foreshadowing)

As a result, the change specifically makes it so the class is much more
direct in what it is exporting, and hopefully makes it easier to digest
on how it is working as well.
  • Loading branch information
NickLaMuro committed Jun 8, 2021
1 parent 470e8b4 commit 2fd1e67
Show file tree
Hide file tree
Showing 3 changed files with 382 additions and 106 deletions.
98 changes: 53 additions & 45 deletions lib/task_helpers/exports/custom_buttons.rb
Original file line number Diff line number Diff line change
@@ -1,60 +1,68 @@
module TaskHelpers
class Exports
class CustomButtons
class ExportArInstances
EXCLUDE_ATTRS = %w(id created_on updated_on created_at updated_at dialog_id resource_id).freeze

def self.export_object(obj, hash)
class_name = obj.class.name.underscore

$log.info("Exporting #{obj.class.name}: #{obj.try('name')} (ID: #{obj&.id})")
attrs = build_attr_list(obj.attributes)
# handle dialog label
attrs["dialog_label"] = obj.dialog&.label if obj.respond_to?(:dialog)
(hash[class_name] ||= []) << item = {'attributes' => attrs}
create_association_list(obj, item)
descendant_list(obj, item)
end
EXCLUDE_ATTRS = %w[id created_on updated_on created_at updated_at dialog_id resource_id].freeze

def self.build_attr_list(attrs)
attrs&.except(*EXCLUDE_ATTRS)
end
def initialize
@export_hash = {}
end

def self.create_association_list(obj, item)
associations = obj.class.try(:reflections)

if associations
associations = associations.collect { |model, assoc| {model => assoc.class.to_s.demodulize} }.select { |as| as.values.first != "BelongsToReflection" && as.keys.first != "all_relationships" }
associations.each do |assoc|
assoc.each do |a|
next if obj.try(a.first.to_sym).blank?
export_object(obj.try(a.first.to_sym), (item['associations'] ||= {}))
end
end
end
def export(options = {})
export_custom_buttons_sets
export_direct_custom_buttons

File.write("#{options[:directory]}/CustomButtons.yaml", YAML.dump(@export_hash))
end

def export_custom_buttons_sets
@export_hash["custom_button_set"] = []

CustomButtonSet.all.order(:id).each do |button_set|
log_export(button_set)

children = {}
export_direct_custom_buttons(button_set.custom_buttons, children)

@export_hash["custom_button_set"] << attrs_for(button_set, children)
end
end

def self.descendant_list(obj, item)
obj.try(:children)&.each { |c| export_object(c, (item['children'] ||= {})) }
def export_direct_custom_buttons(buttons = direct_custom_buttons, result = @export_hash)
result["custom_button"] = []

buttons.each do |custom_button|
log_export(custom_button)

result["custom_button"] << attrs_for(custom_button)
end
end

def export(options = {})
parent_id_list = []
objects = CustomButton.in_region(MiqRegion.my_region_number).order(:id).where.not(:applies_to_class => %w[ServiceTemplate GenericObject])

export = objects.each_with_object({}) do |obj, export_hash|
if obj.try(:parent).present?
next if parent_id_list.include?(obj.parent.id)
ExportArInstances.export_object(obj.parent, export_hash)
parent_id_list << obj.parent.id
else
ExportArInstances.export_object(obj, export_hash)
end
private

def direct_custom_buttons
CustomButton.select("custom_buttons.*, relationships.resource_id")
.left_outer_joins(:all_relationships)
.where(:relationships => {:resource_id => nil})
end

def attrs_for(object, children = nil)
attrs = {}
attrs["attributes"] = object.attributes.except(*EXCLUDE_ATTRS)
attrs["children"] = children if children

if (resource_action = object.try(:resource_action))
attrs["associations"] = {"resource_action" => [attrs_for(resource_action)]}
end

if (label = object.try(:dialog).try(:label))
attrs["attributes"]["dialog_label"] = label
end

export_dir = options[:directory]
File.write("#{export_dir}/CustomButtons.yaml", YAML.dump(export))
attrs
end

def log_export(object)
$log.info("Exporting #{object.class.name}: #{object.try('name')} (ID: #{object&.id})")
end
end
end
Expand Down
Loading

0 comments on commit 2fd1e67

Please sign in to comment.