module PaperTrailAssociationTracking::ModelConfig

Configures an ActiveRecord model, mostly at application boot time, but also sometimes mid-request, with methods like enable/disable.

Public Instance Methods

setup(options = {}) click to toggle source

Set up `@model_class` for PaperTrail. Installs callbacks, associations, “class attributes”, instance methods, and more. @api private

Calls superclass method
# File lib/paper_trail_association_tracking/model_config.rb, line 10
def setup(options = {})
  super

  setup_transaction_callbacks
  setup_callbacks_for_habtm(options[:join_tables])
end

Private Instance Methods

assert_concrete_activerecord_class(class_name) click to toggle source

Raises an error if the provided class is an `abstract_class`. @api private

# File lib/paper_trail_association_tracking/model_config.rb, line 21
def assert_concrete_activerecord_class(class_name)
  if class_name.constantize.abstract_class?
    raise format(::PaperTrail::ModelConfig::E_HPT_ABSTRACT_CLASS, @model_class, class_name)
  end
end
habtm_assocs_not_skipped() click to toggle source
# File lib/paper_trail_association_tracking/model_config.rb, line 27
def habtm_assocs_not_skipped
  @model_class.reflect_on_all_associations(:has_and_belongs_to_many).
    reject { |a| @model_class.paper_trail_options[:skip].include?(a.name.to_s) }
end
setup_callbacks_for_habtm(join_tables) click to toggle source

Adds callbacks to record changes to habtm associations such that on save the previous version of the association (if changed) can be reconstructed.

# File lib/paper_trail_association_tracking/model_config.rb, line 34
def setup_callbacks_for_habtm(join_tables)
  @model_class.send :attr_accessor, :paper_trail_habtm
  @model_class.class_attribute :paper_trail_save_join_tables
  @model_class.paper_trail_save_join_tables = Array.wrap(join_tables)
  habtm_assocs_not_skipped.each(&method(:setup_habtm_change_callbacks))
end
setup_habtm_change_callbacks(assoc) click to toggle source
# File lib/paper_trail_association_tracking/model_config.rb, line 41
def setup_habtm_change_callbacks(assoc)
  assoc_name = assoc.name
  %w[add remove].each do |verb|
    @model_class.send(:"before_#{verb}_for_#{assoc_name}").send(
      :<<,
      lambda do |*args|
        update_habtm_state(assoc_name, :"before_#{verb}", args[-2], args.last)
      end
    )
  end
end
setup_transaction_callbacks() click to toggle source

Reset the transaction id when the transaction is closed.

# File lib/paper_trail_association_tracking/model_config.rb, line 54
def setup_transaction_callbacks
  @model_class.after_commit { ::PaperTrail.request.clear_transaction_id }
  @model_class.after_rollback { ::PaperTrail.request.clear_transaction_id }
end
update_habtm_state(name, callback, model, assoc) click to toggle source
# File lib/paper_trail_association_tracking/model_config.rb, line 59
def update_habtm_state(name, callback, model, assoc)
  model.paper_trail_habtm ||= {}
  model.paper_trail_habtm[name] ||= { removed: [], added: [] }
  state = model.paper_trail_habtm[name]
  assoc_id = assoc.id
  case callback
  when :before_add
    state[:added] |= [assoc_id]
    state[:removed] -= [assoc_id]
  when :before_remove
    state[:removed] |= [assoc_id]
    state[:added] -= [assoc_id]
  else
    raise "Invalid callback: #{callback}"
  end
end