Module: Historyable::ClassMethods

Defined in:
lib/historyable.rb

Instance Method Summary collapse

Instance Method Details

#has_history(*attributes) ⇒ Object

Parameters:

  • attributes (Array, Symbol)


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/historyable.rb', line 19

def has_history(*attributes)
  self.historyable_items = attributes.map do |attribute|
    attribute        = attribute.to_sym
    association_name = attribute.to_s.insert(-1, '_changes').to_sym

    Historyable::Item.new(attribute, association_name)
  end

  # Associations
  historyable_items.each do |historyable|
    has_many historyable.association_name,
             as:         :item,
             class_name: '::Change',
             dependent:  :destroy
  end


  # Instance methods
  historyable_items.each do |historyable|

    # attribute_history_raw
    #
    # @return [ActiveRecord::Relation]
    define_method("#{historyable.attribute.to_s}_history_raw") do
      send(historyable.association_name)
        .where(object_attribute: historyable.attribute)
        .order('created_at DESC')
        .select(:object_attribute_value, :created_at)
    end


    # attribute_history
    #
    # @return [Array]
    define_method("#{historyable.attribute.to_s}_history") do
      unless instance_variable_get("@#{historyable.attribute.to_s}_history".to_sym)
        array = []

        records = send("#{historyable.attribute}_history_raw")
                     .pluck(:object_attribute_value, :created_at)
        records.map do |attribute_value, created_at|
          hash = HashWithIndifferentAccess.new
          hash[:attribute_value] = attribute_value
          hash[:changed_at]      = created_at

          array << hash
        end

        # Sets attribute_history cache
        instance_variable_set("@#{historyable.attribute.to_s}_history".to_sym, array)
        array
      else
        instance_variable_get("@#{historyable.attribute.to_s}_history".to_sym)
      end
    end
  end


  # Callbacks
  around_save :save_changes
end