Source code
class Maintenance::MigrateTreeNodeToMboProfilesTask < MaintenanceTasks::Task
collection_batch_size(1000)
def collection
TreeNode.all
end
def process(tree_node)
mbo_profiles = tree_node.mbo_profiles.reload.to_a
all_custom_fields = collect_all_custom_fields(tree_node)
mbo_profiles = ensure_mbo_profiles_exist(tree_node, mbo_profiles, all_custom_fields)
associate_custom_fields_with_mbo_profiles(all_custom_fields, mbo_profiles, tree_node)
end
def collect_all_custom_fields(tree_node)
custom_field_ids = tree_node.all_custom_field_ids
CustomField.where(id: custom_field_ids)
end
private
def find_orphaned_custom_fields(tree_node)
return CustomField.none unless CustomField.connection.column_exists?(:custom_fields, :tree_node_id)
CustomField.where(custom_fields: { tree_node_id: tree_node.id })
.where.missing(:mbo_profiles)
end
def ensure_mbo_profiles_exist(tree_node, mbo_profiles, all_custom_fields)
return mbo_profiles unless all_custom_fields.exists? && mbo_profiles.empty?
[create_default_mbo_profile(tree_node)]
end
def associate_custom_fields_with_mbo_profiles(all_custom_fields, mbo_profiles, tree_node)
processed_custom_field_ids = Set.new
all_custom_fields.find_each do |cf|
next if processed_custom_field_ids.include?(cf.id)
processed_custom_field_ids.add(cf.id)
if mbo_profiles.empty?
associate_with_new_default_mbo_profile(cf, tree_node)
elsif mbo_profiles.one?
associate_with_single_mbo_profile(cf, mbo_profiles.first)
else
associate_with_all_mbo_profiles(cf, mbo_profiles)
end
end
end
def associate_with_new_default_mbo_profile(custom_field, tree_node)
mbo_profile = create_default_mbo_profile(tree_node)
CustomFieldToMboProfile.find_or_create_by!(custom_field: custom_field, mbo_profile: mbo_profile)
Rails.logger.info(
"Created default MboProfile #{mbo_profile.mbo_id} for TreeNode #{tree_node.id} " \
"and associated CustomField #{custom_field.id}"
)
end
def associate_with_single_mbo_profile(custom_field, mbo_profile)
CustomFieldToMboProfile.find_or_create_by!(custom_field: custom_field, mbo_profile: mbo_profile)
Rails.logger.info(
"Associated CustomField #{custom_field.id} → single MboProfile #{mbo_profile.id}"
)
end
def associate_with_all_mbo_profiles(custom_field, mbo_profiles)
mbo_profiles.each do |mbo|
CustomFieldToMboProfile.find_or_create_by!(custom_field: custom_field, mbo_profile: mbo)
end
Rails.logger.info(
"Associated CustomField #{custom_field.id} → #{mbo_profiles.size} MboProfiles"
)
end
delegate :count, to: :TreeNode
def create_default_mbo_profile(tree_node)
MboProfiles::CreateDefaultMboProfileService.new(tree_node: tree_node).call
end
end