rails_audit_log 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf000427595792f1a97214b6ad5d6dc7f6875681f315570260760accf4e70ba3
4
- data.tar.gz: 8978577023bb75e0832d475b8fcaeaeedb4a02ac3c5b1e1500a6d2187e1c5e5c
3
+ metadata.gz: adf2bbd729f0c0a53c0016389d8b8af4ca66cedede3343bb3376cf880edc447c
4
+ data.tar.gz: 640764fdbe148a2f8d0309350ae74358256b7cc9b530f0c35d0bc045ef736b4c
5
5
  SHA512:
6
- metadata.gz: 897e191130a3895876e5ec8328386d5cd8e456b866a348a0c10edbacc4969883a8ca550e2fa2491f68937ed1a9558c5143a49503c9c80b4f1824789bbc40eee1
7
- data.tar.gz: d1035cdcfcc8d243fc8cfe43fac0842973e9e0dba78e16f4917c83ec83e6db81b8eb999dc441620d01027984ca4a89cdaafb8fb0501b3b98fa4712571d08a706
6
+ metadata.gz: 938374f49a4385c038124abb6aeb95eaa8369dccc20d8eb125e96071954c3b8858cb22dc94781bdfa31e96d006645df5bb07f989c83d4ca35d1792451cb82f07
7
+ data.tar.gz: 82f6ca3524c11b954705d62b576d11c8ae5008f49b26c973789d43466a6d1ab3d4462fd012885a0b83177220c8ceda83c381af5db07e0b371deafca1db14badc
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # RailsAuditLog
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/rails_audit_log.svg)](https://badge.fury.io/rb/rails_audit_log)
3
+ [![CI](https://github.com/eclectic-coding/rails_audit_log/actions/workflows/ci.yml/badge.svg)](https://github.com/eclectic-coding/rails_audit_log/actions/workflows/ci.yml)
4
+ [![Gem Version](https://img.shields.io/gem/v/rails_audit_log.svg)](https://rubygems.org/gems/rails_audit_log)
5
+ [![Downloads](https://img.shields.io/gem/dt/rails_audit_log.svg)](https://rubygems.org/gems/rails_audit_log)
4
6
  [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.3-ruby)](https://www.ruby-lang.org)
5
7
  [![codecov](https://codecov.io/gh/eclectic-coding/rails_audit_log/branch/main/graph/badge.svg)](https://codecov.io/gh/eclectic-coding/rails_audit_log)
6
8
 
data/Rakefile CHANGED
@@ -21,9 +21,9 @@ namespace :dev do
21
21
  dummy_env = { "RAILS_ENV" => "development" }
22
22
  dummy_rake = "cd spec/dummy && bundle exec rake"
23
23
 
24
- desc "Create and migrate the development database"
24
+ desc "Create and load the development database from schema"
25
25
  task :setup do
26
- sh dummy_env, "#{dummy_rake} db:create db:migrate"
26
+ sh dummy_env, "#{dummy_rake} db:create db:schema:load"
27
27
  end
28
28
 
29
29
  desc "Seed the development database"
@@ -31,8 +31,8 @@ namespace :dev do
31
31
  sh dummy_env, "#{dummy_rake} db:seed"
32
32
  end
33
33
 
34
- desc "Drop, recreate, migrate, and seed the development database"
34
+ desc "Drop, recreate, load schema, and seed the development database"
35
35
  task :reset do
36
- sh dummy_env, "#{dummy_rake} db:drop db:create db:migrate db:seed"
36
+ sh dummy_env, "#{dummy_rake} db:drop db:create db:schema:load db:seed"
37
37
  end
38
38
  end
@@ -3,6 +3,9 @@ module RailsAuditLog
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
+ class_attribute :_audit_log_only, default: nil
7
+ class_attribute :_audit_log_ignore, default: nil
8
+
6
9
  has_many :audit_log_entries,
7
10
  class_name: "RailsAuditLog::AuditLogEntry",
8
11
  as: :item,
@@ -13,6 +16,17 @@ module RailsAuditLog
13
16
  after_destroy :record_audit_destroy
14
17
  end
15
18
 
19
+ class_methods do
20
+ def audit_log(only: nil, ignore: nil)
21
+ self._audit_log_only = only.map(&:to_s) if only
22
+ self._audit_log_ignore = ignore.map(&:to_s) if ignore
23
+ end
24
+ end
25
+
26
+ def skip_audit_log
27
+ RailsAuditLog.disable { yield }
28
+ end
29
+
16
30
  private
17
31
 
18
32
  def record_audit_create
@@ -29,15 +43,33 @@ module RailsAuditLog
29
43
  end
30
44
 
31
45
  def record_audit_entry(event, changes)
46
+ return unless RailsAuditLog.enabled?
47
+
48
+ filtered = filter_changes(changes)
49
+ return if filtered.empty? && event == "update"
50
+
32
51
  actor = RailsAuditLog.actor
33
52
  RailsAuditLog::AuditLogEntry.create!(
34
53
  event: event,
35
54
  item_type: self.class.name,
36
55
  item_id: id,
37
- object_changes: changes,
56
+ object_changes: filtered,
38
57
  actor_type: actor&.class&.name,
39
58
  actor_id: actor.respond_to?(:id) ? actor.id : nil
40
59
  )
41
60
  end
61
+
62
+ def filter_changes(changes)
63
+ result = changes.dup
64
+
65
+ if self.class._audit_log_only
66
+ result.select! { |k, _| self.class._audit_log_only.include?(k) }
67
+ else
68
+ ignored = self.class._audit_log_ignore || RailsAuditLog.ignored_attributes
69
+ result.reject! { |k, _| ignored.include?(k) }
70
+ end
71
+
72
+ result
73
+ end
42
74
  end
43
75
  end
@@ -11,8 +11,52 @@ module RailsAuditLog
11
11
  validates :item_type, presence: true
12
12
  validates :item_id, presence: true
13
13
 
14
- scope :creates, -> { where(event: "create") }
15
- scope :updates, -> { where(event: "update") }
16
- scope :destroys, -> { where(event: "destroy") }
14
+ # Event scopes
15
+ scope :created_events, -> { where(event: "create") }
16
+ scope :updated_events, -> { where(event: "update") }
17
+ scope :destroyed_events, -> { where(event: "destroy") }
18
+
19
+ # Deprecated short aliases kept for backwards compatibility
20
+
21
+ scope :creates, -> { created_events }
22
+ scope :updates, -> { updated_events }
23
+ scope :destroys, -> { destroyed_events }
24
+
25
+ # Actor / resource scopes
26
+ scope :by_actor, ->(actor) { where(actor_type: actor.class.name, actor_id: actor.id) }
27
+ scope :for_resource, lambda { |resource|
28
+ if resource.is_a?(Class)
29
+ where(item_type: resource.name)
30
+ else
31
+ where(item_type: resource.class.name, item_id: resource.id)
32
+ end
33
+ }
34
+
35
+ # Time scopes
36
+ scope :since, ->(time) { where(created_at: time..) }
37
+ scope :until, ->(time) { where(created_at: ..time) }
38
+
39
+ # Instance methods
40
+
41
+ def changed_attributes
42
+ object_changes&.keys || []
43
+ end
44
+
45
+ def diff
46
+ return {} unless object_changes
47
+
48
+ object_changes.transform_values { |from_to| { from: from_to[0], to: from_to[1] } }
49
+ end
50
+
51
+ # Attribute scope — uses json_extract (SQLite/MySQL) or json ? key (PostgreSQL)
52
+ scope :touching, ->(attribute) {
53
+ if connection.adapter_name =~ /PostgreSQL/i
54
+ # :nocov:
55
+ where("object_changes ? :key", key: attribute.to_s)
56
+ # :nocov:
57
+ else
58
+ where("json_extract(object_changes, ?) IS NOT NULL", "$.#{attribute}")
59
+ end
60
+ }
17
61
  end
18
62
  end
@@ -1,3 +1,3 @@
1
1
  module RailsAuditLog
2
- VERSION = "0.1.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -2,6 +2,10 @@ require "rails_audit_log/version"
2
2
  require "rails_audit_log/engine"
3
3
 
4
4
  module RailsAuditLog
5
+ # Global default columns to ignore across all audited models.
6
+ # Override in an initializer: RailsAuditLog.ignored_attributes = %w[updated_at cached_at]
7
+ mattr_accessor :ignored_attributes, default: %w[updated_at]
8
+
5
9
  def self.actor
6
10
  Thread.current[:rails_audit_log_actor]
7
11
  end
@@ -17,4 +21,16 @@ module RailsAuditLog
17
21
  ensure
18
22
  self.actor = previous
19
23
  end
24
+
25
+ def self.enabled?
26
+ !Thread.current[:rails_audit_log_disabled]
27
+ end
28
+
29
+ def self.disable
30
+ previous = Thread.current[:rails_audit_log_disabled]
31
+ Thread.current[:rails_audit_log_disabled] = true
32
+ yield
33
+ ensure
34
+ Thread.current[:rails_audit_log_disabled] = previous
35
+ end
20
36
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_audit_log
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chuck Smith