class DataWorks::ParentCreator

Public Class Methods

new(works, model_name, model_attrs) click to toggle source
# File lib/data_works/parent_creator.rb, line 4
def initialize(works, model_name, model_attrs)
  @works = works
  @model_name = model_name.to_sym
  @parents = {}
end

Public Instance Methods

create_necessary_parents(parents_we_already_have) click to toggle source

This returns a hash of the parent models created, so that they can be easily merged into a model attribute hash. For example, if a school parent model was created for a student model, then it would be returned like so:

{ :school => the_school_model }
# File lib/data_works/parent_creator.rb, line 15
def create_necessary_parents(parents_we_already_have)
  for missing_necessary_parent in missing_necessary_parents(parents_we_already_have)
    find_or_add(missing_necessary_parent)
  end
  @parents
end

Private Instance Methods

destroy_zombie_child_of(parent_model) click to toggle source
# File lib/data_works/parent_creator.rb, line 61
def destroy_zombie_child_of(parent_model)
  child = parent_model.send(@model_name)
  child.destroy if child.persisted? && !child.destroyed?
end
destroy_zombies(parent_model, parent_association_name) click to toggle source

Consider the case where a model has a has_one relationship with its child. The model autocreates the child model using a callback like before_validation or after_initialize.

This can confuse DataWorks because DataWorks creates models by starting at the child and creating all of the necessary ancestors. It's a “child creates parent” strategy. When a model class autocreates a child, it happens outside of DataWorks so DataWorks does not know about it and it goes against the flow since it has a “parent creates child” strategy.

The upshot is that a bunch of unmanaged zombie objects will be lying around that could disrupt tests. So we specifically have to delete any model objects that a parent may have created outside of DataWorks before they cause trouble.

# File lib/data_works/parent_creator.rb, line 51
def destroy_zombies(parent_model, parent_association_name)
  if zombies_possible?(parent_association_name)
    destroy_zombie_child_of(parent_model)
  end
end
find_or_add(necessary_parent) click to toggle source
# File lib/data_works/parent_creator.rb, line 30
def find_or_add(necessary_parent)
  parent_model = @works.find_or_add(necessary_parent.model_name)
  destroy_zombies(parent_model, necessary_parent.association_name)
  @parents[necessary_parent.association_name] = parent_model
end
missing_necessary_parents(parents_we_already_have) click to toggle source
# File lib/data_works/parent_creator.rb, line 24
def missing_necessary_parents(parents_we_already_have)
  Relationships.necessary_parents_for(@model_name).reject do |necessary_parent|
    parents_we_already_have.include?(necessary_parent.association_name)
  end
end
zombies_possible?(parent_association_name) click to toggle source
# File lib/data_works/parent_creator.rb, line 57
def zombies_possible?(parent_association_name)
  Relationships.autocreated_children_of(parent_association_name).include?(@model_name)
end