ManageIQ/inventory_refresh

View on GitHub
lib/inventory_refresh/inventory_collection/reference.rb

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
require "active_support/core_ext/module/delegation"

module InventoryRefresh
  class InventoryCollection
    class Reference
      attr_reader :full_reference, :keys, :ref, :stringified_reference

      delegate :[], :to => :full_reference

      # @param data [Hash, String] Data needed for creating the reference
      # @param ref [String] Name of the reference (and of the index associated)
      # @param keys [Array<Symbol>] Attribute/column names of the reference, that are used as indexes of the passed
      #        data hash
      def initialize(data, ref, keys)
        @full_reference = build_full_reference(data, keys)
        @ref            = ref
        @keys           = keys

        @nested_secondary_index = keys.select { |key| full_reference[key].kind_of?(InventoryRefresh::InventoryObjectLazy) }.any? do |key|
          !full_reference[key].primary?
        end

        @stringified_reference = self.class.build_stringified_reference(full_reference, keys)
      end

      # Return true if reference is to primary index, false otherwise. Reference is primary, only if all the nested
      # references are primary.
      #
      # @return [Boolean] true if reference is to primary index, false otherwise
      def primary?
        ref == :manager_ref && !nested_secondary_index
      end

      def nested_secondary_index?
        nested_secondary_index
      end

      def loadable?
        keys.any? { |attribute| full_reference[attribute].present? }
      end

      class << self
        # Builds string uuid from passed Hash and keys
        #
        # @param hash [Hash] Hash data
        # @param keys [Array<Symbol>] Indexes into the Hash data
        # @return [String] Concatenated values on keys from data
        def build_stringified_reference(hash, keys)
          stringify_reference(keys.map { |attribute| hash[attribute].to_s })
        end

        # Builds string uuid from passed Object and keys
        #
        # @param record [ApplicationRecord] ActiveRecord record
        # @param keys [Array<Symbol>] Indexes into the Hash data
        # @return [String] Concatenated values on keys from data
        def build_stringified_reference_for_record(record, keys)
          stringify_reference(keys.map { |attribute| record.public_send(attribute).to_s })
        end

        # Returns passed array joined by stringify_joiner
        #
        # @param reference [Array<String>]
        # @return [String] Passed array joined by stringify_joiner
        def stringify_reference(reference)
          reference.join(stringify_joiner)
        end

        private

        # Returns joiner for string UIID
        #
        # @return [String] Joiner for string UIID
        def stringify_joiner
          "__"
        end
      end

      private

      # @return Returns true if reference has nested references that are not pointing to primary index, but to
      #         secondary indexes.
      attr_reader :nested_secondary_index

      # Returns original Hash, or build hash out of passed string
      #
      # @param data [Hash, String] Passed data
      # @param keys [Array<Symbol>] Keys for the reference
      # @return [Hash] Original Hash, or build hash out of passed string
      def build_full_reference(data, keys)
        if data.kind_of?(Hash)
          data
        else
          raise "Please provide Hash as a reference, :manager_ref count includes more than 1 attribute. keys: #{keys}, data: #{data}" if keys.size > 1

          {keys.first => data}
        end
      end
    end
  end
end