Module: Moribus::AggregatedBehavior

Extended by:
ActiveSupport::Concern
Defined in:
lib/moribus/aggregated_behavior.rb

Overview

Adds aggregated behavior to a model. An aggregated model tries to insure it will not duplicate itself for whatever parents it belongs to. Whenever an aggregated model is about to be saved, it uses its attributes to perform a lookup for an existing record with the same attributes. If the lookup succeeds, its id is used to replace id of model being saved, and no ‘INSERT’ statement is executed. If the lookup fails, the original AR save routines are performed.

This behavior ignores by default the columns it doesn’t consider to contain content such as the ones created and used by ActiveRecord. These can be expanded through the API: @example:

acts_as_aggregated :non_content_columns => %w(some other colums)

Instance Method Summary collapse

Instance Method Details

#saveObject

Override the original AR::Base #save method with the aggregated behavior. This cannot be done using a before_save callback, because, if the lookup succeeds, we don’t want the original #save to be executed. But if false is returned by the callback, it will also be returned by the #save method, wrongly indicating the result of saving.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/moribus/aggregated_behavior.rb', line 29

def save(*)
  @updated_as_aggregated = false
  run_callbacks(:save) do
    return (lookup_self_and_replace or super) if new_record?

    is_any_content_attr_changed =
      attributes.except(*aggregated_behaviour_non_content_columns).keys.
        any?{ |attr| attribute_changed?(attr) }

    if is_any_content_attr_changed
      to_new_record!
      lookup_self_and_replace or return super

      true
    else
      super
    end
  end
end

#save!(*args) ⇒ Object

Bang version of #save.



50
51
52
# File 'lib/moribus/aggregated_behavior.rb', line 50

def save!(*args)
  save(*args) or raise ActiveRecord::RecordNotSaved
end