Class: EffectiveLogging::ActiveRecordLogger

Inherits:
Object
  • Object
show all
Defined in:
lib/effective_logging/active_record_logger.rb

Constant Summary collapse

BLANK =
"''"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(object, options = {}) ⇒ ActiveRecordLogger

Returns a new instance of ActiveRecordLogger.

Raises:

  • (ArgumentError)


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/effective_logging/active_record_logger.rb', line 7

def initialize(object, options = {})
  raise ArgumentError.new('options must be a Hash') unless options.kind_of?(Hash)

  @object = object
  @resource = Effective::Resource.new(object)

  @logger = options.fetch(:logger, object)
  @depth = options.fetch(:depth, 0)
  @include_associated = options.fetch(:include_associated, true)
  @include_nested = options.fetch(:include_nested, true)
  @log_parents = options.fetch(:log_parents, true)
  @options = options

  raise ArgumentError.new('logger must respond to logged_changes') unless @logger.respond_to?(:logged_changes)
end

Instance Attribute Details

#depthObject

Returns the value of attribute depth.



3
4
5
# File 'lib/effective_logging/active_record_logger.rb', line 3

def depth
  @depth
end

#include_associatedObject

Returns the value of attribute include_associated.



3
4
5
# File 'lib/effective_logging/active_record_logger.rb', line 3

def include_associated
  @include_associated
end

#include_nestedObject

Returns the value of attribute include_nested.



3
4
5
# File 'lib/effective_logging/active_record_logger.rb', line 3

def include_nested
  @include_nested
end

#log_parentsObject

Returns the value of attribute log_parents.



3
4
5
# File 'lib/effective_logging/active_record_logger.rb', line 3

def log_parents
  @log_parents
end

#loggerObject

Returns the value of attribute logger.



3
4
5
# File 'lib/effective_logging/active_record_logger.rb', line 3

def logger
  @logger
end

#objectObject

Returns the value of attribute object.



3
4
5
# File 'lib/effective_logging/active_record_logger.rb', line 3

def object
  @object
end

#optionsObject

Returns the value of attribute options.



3
4
5
# File 'lib/effective_logging/active_record_logger.rb', line 3

def options
  @options
end

#resourceObject

Returns the value of attribute resource.



3
4
5
# File 'lib/effective_logging/active_record_logger.rb', line 3

def resource
  @resource
end

Instance Method Details

#created!Object



41
42
43
# File 'lib/effective_logging/active_record_logger.rb', line 41

def created!
  log('Created', applicable(instance_attributes))
end

#destroyed!Object



37
38
39
# File 'lib/effective_logging/active_record_logger.rb', line 37

def destroyed!
  log('Deleted', applicable(instance_attributes))
end

#execute!Object



23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/effective_logging/active_record_logger.rb', line 23

def execute!
  @logged = false

  if new_record?(object)
    created!
  elsif destroyed_record?(object)
    destroyed!
  else
    updated!
  end

  logged?
end

#log(message, details) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/effective_logging/active_record_logger.rb', line 88

def log(message, details)
  log = logger.logged_changes.build(
    user: EffectiveLogging.current_user,
    status: EffectiveLogging.log_changes_status,
    message: "#{"\t" * depth}#{options[:prefix]}#{message}",
    associated_to_s: (logger.to_s rescue nil),
    details: (details.presence || {})
  )

  log_changes_to_parents(message, details) if depth == 0 && log_parents

  @logged = log.save!
  log
end

#log_changes_to_parents(message, details) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/effective_logging/active_record_logger.rb', line 103

def log_changes_to_parents(message, details)
  log_changes_parents.each do |parent|
    title = object.class.name.to_s.singularize.titleize
    parent_options = { logger: parent, prefix: "#{title} - #{object} - " }
    ActiveRecordLogger.new(parent, parent_options).log(message, details)
  end
end

#log_nested_resources!Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/effective_logging/active_record_logger.rb', line 70

def log_nested_resources!
  return unless include_nested

  # Log changes on all accepts_as_nested_parameters has_many associations
  resource.nested_resources.each do |association|
    title = association.name.to_s.singularize.titleize

    Array(object.send(association.name)).each_with_index do |child, index|
      next unless child.present?

      child_options = options.merge(logger: logger, depth: depth+1, prefix: "#{title} #{index} - #{child} - ", include_associated: include_associated, include_nested: include_nested)
      child_options = child_options.merge(child.log_changes_options) if child.respond_to?(:log_changes_options)

      @logged = true if ActiveRecordLogger.new(child, child_options).execute!
    end
  end
end

#log_resource_changes!Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/effective_logging/active_record_logger.rb', line 52

def log_resource_changes!
  applicable(resource.instance_changes).each do |attribute, (before, after)|
    if object.respond_to?(:log_changes_formatted_value)
      before = object.log_changes_formatted_value(attribute, before) || before
      after = object.log_changes_formatted_value(attribute, after) || after
    end

    before = before.to_s if before.kind_of?(ActiveRecord::Base) || before.kind_of?(FalseClass)
    after = after.to_s if after.kind_of?(ActiveRecord::Base) || after.kind_of?(FalseClass)

    attribute = if object.respond_to?(:log_changes_formatted_attribute)
      object.log_changes_formatted_attribute(attribute)
    end || attribute.titleize

    log("#{attribute}: #{before.presence || BLANK} → #{after.presence || BLANK}", { attribute: attribute, before: before, after: after })
  end
end

#updated!Object



45
46
47
48
49
50
# File 'lib/effective_logging/active_record_logger.rb', line 45

def updated!
  log_resource_changes!
  log_nested_resources!

  (logged? && depth == 0) ? log('Updated', applicable(instance_attributes)) : true
end