lib/syncify/sync.rb in syncify-0.1.6 vs lib/syncify/sync.rb in syncify-0.1.10

- old
+ new

@@ -19,16 +19,17 @@ puts 'Identifying records to sync...' @identified_records = Set[] @has_and_belongs_to_many_associations = {} remote do + associations = normalized_associations(association) initial_query.each do |root_record| - identify_associated_records(root_record, normalized_associations(association)) + identify_associated_records(root_record, associations) end end - puts "Identified #{identified_records.size} records to sync." + puts "\nIdentified #{identified_records.size} records to sync." callback.call(identified_records) if callback.present? sync_records end @@ -49,43 +50,58 @@ 'Please provide either the id argument or the where argument, but not both.') end end def print_status - print "\rIdentified #{identified_records.size} records..." + @identified_records_count ||= identified_records.size + if @identified_records_count != identified_records.size + puts "Identified #{identified_records.size} records..." + @identified_records_count = identified_records.size + end end def identify_associated_records(root, associations) identified_records << root print_status standard_associations = associations.reject(&method(:includes_polymorphic_association)) polymorphic_associations = associations.select(&method(:includes_polymorphic_association)) standard_associations.each do |association| - traverse_associations(root.class.eager_load(association).find(root.id), association) + begin + traverse_associations(root.class.eager_load(association).find(root.id), association) + rescue StandardError => e + binding.pry + x = 1231231231 + end end identify_polymorphic_associated_records(root, polymorphic_associations) end def identify_polymorphic_associated_records(root, polymorphic_associations) polymorphic_associations.each do |polymorphic_association| - if polymorphic_association.is_a?(Hash) - polymorphic_association.each do |key, association| - Array.wrap(root.__send__(key)).each do |target| - identify_polymorphic_associated_records(target, Array.wrap(association)) - end + property = polymorphic_association.keys.first + nested_associations = polymorphic_association[property] + + referenced_objects = Array.wrap(root.__send__(property)) + next if referenced_objects.empty? + + referenced_objects.each do |referenced_object| + # TODO: there's got to be a better way to express this + if polymorphic_association.values.first.keys.all? { |key| key.is_a? Class } + # TODO: please, Doug. Fix the names!!! + associated_types = nested_associations.keys + referenced_type = associated_types.find { |type| referenced_object.is_a?(type) } + + identify_associated_records( + referenced_object, + normalized_associations(nested_associations[referenced_type]) + ) + else + identify_associated_records(referenced_object, normalized_associations(nested_associations)) end - else - target = root.__send__(polymorphic_association.property) - next if target.nil? - type = polymorphic_association.associations.keys.detect do |association_type| - target.is_a?(association_type) - end - associations = polymorphic_association.associations[type] - identify_associated_records(target, normalized_associations(associations)) end end end def traverse_associations(records, associations) @@ -94,21 +110,22 @@ identified_records.merge records print_status records.each do |record| associations.each do |association, nested_associations| - if is_through_association?(record, association) + puts "Traversing #{record.class.name}##{association}" + if through_association?(record, association) traverse_associations( record.__send__( record.class.reflect_on_association(association).through_reflection.name ), associations ) else associated_records = record.__send__(association) - if is_has_and_belongs_to_many_association?(record, association) + if has_and_belongs_to_many_association?(record, association) cache_has_and_belongs_to_many_association(record, association, associated_records) end traverse_associations(associated_records, nested_associations) end @@ -119,16 +136,16 @@ def cache_has_and_belongs_to_many_association(record, association, associated_records) has_and_belongs_to_many_associations[record] ||= {} has_and_belongs_to_many_associations[record][association] = Array(associated_records) end - def is_has_and_belongs_to_many_association?(record, association) + def has_and_belongs_to_many_association?(record, association) record.class.reflect_on_association(association).class == ActiveRecord::Reflection::HasAndBelongsToManyReflection end - def is_through_association?(record, association) + def through_association?(record, association) record.class.reflect_on_association(association).class == ActiveRecord::Reflection::ThroughReflection end def sync_records @@ -140,16 +157,21 @@ clazz.import(new_instances, validate: false) end has_and_belongs_to_many_associations.each do |record, associations| associations.each do |association, associated_records| - local_record = record.class.find(record.id) - local_associated_records = associated_records.map do |associated_record| - associated_record.class.find(associated_record.id) + begin + local_record = record.class.find(record.id) + local_associated_records = associated_records.map do |associated_record| + associated_record.class.find(associated_record.id) + end + local_record.__send__(association) << local_associated_records + local_record.save + rescue StandardError => e + binding.pry + x = 123 end - local_record.__send__(association) << local_associated_records - local_record.save end end end end @@ -174,10 +196,14 @@ new_instance end def includes_polymorphic_association(association) - association.to_s.include?('Syncify::PolymorphicAssociation') + return false if association.nil? + return false if association == {} + return true if association.keys.all? { |key| key.is_a? Class } + + includes_polymorphic_association(association.values.first) end def normalized_associations(association) Syncify::NormalizeAssociations.run!(association: association) end