class Syncify::IdentifyAssociations

Attributes

association_registry[RW]
identified_associations[RW]

Public Instance Methods

execute() click to toggle source
# File lib/syncify/identify_associations.rb, line 9
def execute
  @association_registry = Set[]
  @identified_associations = {}

  remote do
    identify_associations(klass, identified_associations)

    simplify_associations(traverse_associations)
  end
end

Private Instance Methods

applicable_associations(klass) click to toggle source
# File lib/syncify/identify_associations.rb, line 105
def applicable_associations(klass)
  klass.
    reflect_on_all_associations.
    reject(&method(:inapplicable_associations))
end
identify_associations(from_class, destination) click to toggle source
# File lib/syncify/identify_associations.rb, line 45
def identify_associations(from_class, destination)
  applicable_associations(from_class).each do |association|
    puts "Inspecting #{from_class.name}##{association.name}"
    pending_association = if association.polymorphic?
                            Syncify::Association::PolymorphicAssociation.new(
                              from_class: from_class,
                              association: association,
                              destination: destination
                            )
                          else
                            Syncify::Association::StandardAssociation.new(
                              from_class: from_class,
                              association: association,
                              destination: destination
                            )
                          end

    association_registry << pending_association
  end
end
inapplicable_associations(association) click to toggle source
# File lib/syncify/identify_associations.rb, line 111
def inapplicable_associations(association)
  return true if association.class == ActiveRecord::Reflection::ThroughReflection

  hints.each do |hint|
    return !hint.allowed? if hint.applicable?(association)
  end

  false
end
next_untraversed_association() click to toggle source
# File lib/syncify/identify_associations.rb, line 101
def next_untraversed_association
  association_registry.find { |association| !association.traversed }
end
remote() { || ... } click to toggle source

TODO: this is duplicated from Sync. Consider refactoring

# File lib/syncify/identify_associations.rb, line 122
def remote
  run_in_environment(remote_database) { yield }
end
run_in_environment(environment) { || ... } click to toggle source
# File lib/syncify/identify_associations.rb, line 126
def run_in_environment(environment)
  initial_config = ActiveRecord::Base.connection_config
  ActiveRecord::Base.establish_connection environment
  yield
ensure
  ActiveRecord::Base.establish_connection initial_config
end
should_ignore_association?(association) click to toggle source
# File lib/syncify/identify_associations.rb, line 90
def should_ignore_association?(association)
  # ignore if association is the inverse of an association that has already been traversed
  traversed_associations.find do |traversed_association|
    traversed_association.inverse_of?(association)
  end
end
simplify_associations(associations) click to toggle source
# File lib/syncify/identify_associations.rb, line 22
def simplify_associations(associations)
  simplified_associations = associations.each.reduce([]) do |memo, (association, nested_association)|
    simplified_association = if association.is_a? Class
                               { association => simplify_associations(nested_association) }
                             elsif nested_association.empty?
                               association
                             else
                               { association => simplify_associations(nested_association) }
                             end

    memo << simplified_association
    memo
  end

  if simplified_associations.map(&:class).uniq == [Hash]
    return simplified_associations.inject({}) { |memo, association| memo.merge(association) }
  end
  return simplified_associations.first if simplified_associations.size == 1
  return nil if simplified_associations.empty?

  simplified_associations
end
traverse_associations() click to toggle source
# File lib/syncify/identify_associations.rb, line 66
def traverse_associations
  while (association = next_untraversed_association)
    association.traversed = true

    next if should_ignore_association?(association)

    if association.polymorphic?
      association.to_classes.each do |to_class|
        identify_associations(
          to_class,
          association.create_destination(to_class)
        )
      end
    else
      identify_associations(
        association.to_class,
        association.create_destination(association.name)
      )
    end
  end

  identified_associations
end
traversed_associations() click to toggle source
# File lib/syncify/identify_associations.rb, line 97
def traversed_associations
  association_registry.select { |association| association.traversed }
end