Sha256: fb174462c9e479828b48a0cd223d425af5465a3d0e586887ba4f5920af3f1617

Contents?: true

Size: 1.98 KB

Versions: 5

Compression:

Stored size: 1.98 KB

Contents

class ActiveShepherd::Methods::ApplyState < ActiveShepherd::ApplyMethod
  def apply_state
    mark_all_associated_objects_for_destruction
    apply_default_state_to_root_model
    traverse!
  end

  def handle_attribute(attribute_name, raw_value)
    value = aggregate.deserialize_value attribute_name, raw_value
    aggregate.model.send "#{attribute_name}=", value
  end

  def handle_has_many_association(reflection, collection_state)
    association = aggregate.model.send reflection.name
    collection_state.each do |state|
      associated_model = association.build
      self.class.apply_state recurse(associated_model, reflection.foreign_key),
        state
    end
  end

  def handle_has_one_association(reflection, state)
    associated_model = aggregate.model.send "build_#{reflection.name}"
    self.class.apply_state recurse(associated_model, reflection.foreign_key),
      state
  end

private

  def apply_default_state_to_root_model
    default_attributes = aggregate.default_attributes
    ignored_attribute_names = attributes.keys.map(&:to_s) + aggregate.excluded_attributes

    (default_attributes.keys - ignored_attribute_names).each do |attribute_name|
      current_value = aggregate.model.attributes[attribute_name]
      default_value = default_attributes[attribute_name]

      unless aggregate.deserialize_value(attribute_name, default_value) == default_value
        raise 'Have not handled this use case yet; serialized attributes with a default value'
      end

      next if default_value == current_value

      aggregate.model.send("#{attribute_name}=", default_value)
    end
  end

  def mark_all_associated_objects_for_destruction
    aggregate.traversable_associations.each do |name, association_reflection|
      if association_reflection.macro == :has_many
        aggregate.model.send(name).each { |record| record.mark_for_destruction }
      elsif association_reflection.macro == :has_one
        aggregate.model.send(name).try(&:mark_for_destruction)
      end
    end
  end
end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
activeshepherd-0.8.4 lib/active_shepherd/methods/apply_state.rb
activeshepherd-0.8.3 lib/active_shepherd/methods/apply_state.rb
activeshepherd-0.8.2 lib/active_shepherd/methods/apply_state.rb
activeshepherd-0.8.1 lib/active_shepherd/methods/apply_state.rb
activeshepherd-0.8.0 lib/active_shepherd/methods/apply_state.rb