logga 2.1.2 → 4.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e701347d79260bff1bb8db40f220512a456720b66efa246de76dac9a9790bac2
4
- data.tar.gz: a8b56e341270752b63f5d1195232e0ac90972d3e66bf0368561b0775ea45e99d
3
+ metadata.gz: 5075dc703ff0a06e13b0ca7893c668bc7da0a60bc24032697ec8175d25ba6ce3
4
+ data.tar.gz: 6a5242a25eaa02ce127a6af099b58e708fe020b0dc17f2ffa3e603644e69b645
5
5
  SHA512:
6
- metadata.gz: 4991d4f6fb02cb56c5f3b952416fb2c58209eae7a84d65d8db9147b797cab1c40af9123d1be4e70a4b59a9d5a46247f7a1a913695558bf9d7641e76b1fcc38c0
7
- data.tar.gz: ccdd5e59e29546563dc5cbba93796682dcdb07286aa91da7974d544daa41a3d43724b93d749d41b7dd5e957240f08f0b9ca062e74e22242d4c22e727dc34e799
6
+ metadata.gz: '032693244e4731bf72f85c44a864da4b7b3c7ae8486fd05528ec499dc2768c41343d0e507864bd8807162e96ddad396cbc387228169357910dbc9ceaeb0d3912'
7
+ data.tar.gz: af16e0fafb5da9d8c2c7c9b88d2e4fec44d8e0508ba101f83a6d94ee7e0b3fadf8bff5624531b7ff6e5c2ac95effb831c396f80e1c78f31673bc4c9b0e28e871
data/README.md CHANGED
@@ -2,7 +2,12 @@
2
2
 
3
3
  Provides attribute logging functionality to ActiveRecord objects.
4
4
 
5
- [![CircleCI](https://circleci.com/gh/boxt/logga/tree/master.svg?style=svg&circle-token=f9550ac25744c292e3680638bad3d5deafb1c4e1)](https://circleci.com/gh/boxt/logga/tree/master)
5
+ [![Gem Version](https://badge.fury.io/rb/logga.svg)](https://badge.fury.io/rb/logga)
6
+ [![CI](https://github.com/boxt/logga/actions/workflows/ci.yml/badge.svg)](https://github.com/boxt/logga/actions/workflows/ci.yml)
7
+
8
+ ## Requirements
9
+
10
+ * Ruby 2.7 or above
6
11
 
7
12
  ## Installation
8
13
 
@@ -26,27 +31,94 @@ gem install logga
26
31
 
27
32
  ## Usage
28
33
 
29
- Add this to your model:
34
+ Add the following to your model:
30
35
 
31
36
  ```ruby
32
- class Order < ApplicationRecord
33
- add_log_entries_for :create, :update
37
+ class Thing < ApplicationRecord
38
+ # Optional author accessor. See #author
39
+ attr_accessor :author
40
+
41
+ # Association to :log_entries, which the loggable object must response to for logging.
42
+ has_many :log_entries, as: :loggable, dependent: :destroy
43
+
44
+ add_log_entries_for(
45
+ :create, # Log on object create
46
+ :delete, # Log on object delete
47
+ :update, # Log on object update
48
+ allowed_fields: [], # set an array of fields allowed to be logged
49
+ exclude_fields: [], # set an array of fields excluded from logging. Ignored if allowed_fields is set
50
+ fields: {}, # Custom messages for fields. See #fields
51
+ to: nil
52
+ )
34
53
  end
35
54
  ```
36
55
 
37
- So that new LogEntry records attached to a given Order instance will be created whenever a new one is created or
56
+ So that new `LogEntry` records attached to a given `Thing` instance will be created whenever a new one is created or
38
57
  modified.
39
58
 
59
+ ## Author
60
+
61
+ If you want to log the author of the changes you can do so by setting:
62
+
63
+ ```ruby
64
+ thing.author = { id: "1", name: "Barry", type: "User" }
65
+ ```
66
+
67
+ ## Fields
68
+
69
+ You can override the default messages per field by using:
70
+
71
+ ```ruby
72
+ add_log_entries_for(
73
+ :update,
74
+ fields: {
75
+ name: lambda { |record, field, old_value, new_value|
76
+ "Name changed from #{old_value} to #{new_value}"
77
+ }
78
+ }
79
+ )
80
+ ```
81
+
82
+ This is with the exeception on `:created_at` which only takes the created record.
83
+
84
+ ```ruby
85
+ add_log_entries_for(
86
+ :create,
87
+ fields: {
88
+ created_at: lambda { |record|
89
+ "Created object with id: #{record.id}"
90
+ }
91
+ }
92
+ )
93
+ ```
94
+
95
+ ## Configuration
96
+
97
+ Add an initializer to your project:
98
+
99
+ ```ruby
100
+ Logga.configure do |config|
101
+ config.enabled = true
102
+ config.excluded_fields = [] # Default array of excluded fields i.e. [:id] to ignore all :id fields for every object
103
+ config.excluded_suffixes = [] # Array of excluded suffixes i.e. [:_id] to ignore all fields that end in :_id for every object
104
+ end
105
+ ```
106
+
107
+ For example:
108
+
109
+ ```ruby
110
+ Logga.configure do |config|
111
+ config.excluded_fields = [:id] # Don't log any id changes
112
+ config.excluded_suffixes = [_id] # Don't log any column that ends in _id
113
+ end
114
+ ```
115
+
40
116
  ## Development
41
117
 
42
118
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
43
119
 
44
120
  To install this gem onto your local machine, run `bundle exec rake install`.
45
121
 
46
- ## Versioning
47
-
48
- The version of the gem should be set in the `VERSION` file found in the root of the project. This is then read by the `lib/boxt_aasm_ext/version.rb` file to set in the gem.
49
-
50
122
  ## Contributing
51
123
 
52
124
  Bug reports and pull requests are welcome on GitHub at https://github.com/boxt/logga.
@@ -57,5 +129,5 @@ The gem is available as open source under the terms of the [MIT License](http://
57
129
 
58
130
  ## TODOs
59
131
 
60
- - Write some tests
61
132
  - Improve the documentation
133
+ - Add migration generator for `:log_entries`
data/VERSION CHANGED
@@ -1 +1,2 @@
1
- 2.1.2
1
+ 4.0.2
2
+
@@ -4,25 +4,26 @@ module Logga
4
4
  module ActiveRecord
5
5
  extend ActiveSupport::Concern
6
6
 
7
- EXCLUDED_KEYS = %i[id created_at deleted_at initial updated_at log sent_after_sales_emails].freeze
8
- EXCLUDED_KEYS_SUFFIXES = %i[_id _filenames].freeze
9
-
10
7
  included do
11
- class_attribute :log_fields, instance_writer: false
8
+ class_attribute :allowed_fields, instance_writer: false
12
9
  class_attribute :excluded_fields, instance_writer: false
13
- self.log_fields = {}
14
- self.excluded_fields = {}
10
+ class_attribute :fields, instance_writer: false
11
+
12
+ self.allowed_fields = []
13
+ self.excluded_fields = []
14
+ self.fields = {}
15
15
  end
16
16
 
17
17
  class_methods do
18
- def add_log_entries_for(*actions, to: :self, fields: {}, exclude_fields: [])
19
- after_create :log_model_creation if actions.include?(:create)
18
+ def add_log_entries_for(*actions, allowed_fields: [], exclude_fields: [], fields: {}, to: :self)
19
+ after_create :log_model_creation if actions.include?(:create)
20
20
  after_destroy :log_model_deletion if actions.include?(:delete)
21
- after_update :log_model_changes if actions.include?(:update)
21
+ after_update :log_model_changes if actions.include?(:update)
22
22
  define_method(:log_receiver) { to == :self ? self : send(to) }
23
23
 
24
- self.log_fields = fields
25
- self.excluded_fields = Array(exclude_fields)
24
+ self.allowed_fields = Array(allowed_fields)
25
+ self.excluded_fields = allowed_fields.blank? ? Array(exclude_fields) : []
26
+ self.fields = fields
26
27
  end
27
28
  end
28
29
 
@@ -30,27 +31,29 @@ module Logga
30
31
  return if changes.blank?
31
32
 
32
33
  body = field_changes_to_message(changes)
33
- create_log_entry(author_data.merge(body: body)) if body.present?
34
+ return if body.blank?
35
+
36
+ create_log_entry(author_data.merge(body: body))
34
37
  end
35
38
 
36
39
  def log_model_creation
37
- return if should_not_log?
40
+ return unless should_log?
38
41
 
39
42
  body_generator = ->(record) { default_creation_log_body(record) }
40
- body = log_fields.fetch(:created_at, body_generator).call(self)
43
+ body = fields.fetch(:created_at, body_generator).call(self)
41
44
  create_log_entry(author_data.merge(body: body, created_at: creation_at))
42
45
  end
43
46
 
44
47
  def log_model_deletion
45
- return if should_not_log?
48
+ return unless should_log?
46
49
 
47
50
  body_generator = ->(record) { default_deletion_log_body(record) }
48
- body = log_fields.fetch(:deleted_at, body_generator).call(self)
51
+ body = fields.fetch(:deleted_at, body_generator).call(self)
49
52
  create_log_entry(author_data.merge(body: body))
50
53
  end
51
54
 
52
55
  def log_model_changes
53
- return if should_not_log?
56
+ return unless should_log?
54
57
 
55
58
  field_changes = previous_changes.reject { |k, _| reject_change?(k) }
56
59
  log_field_changes(field_changes)
@@ -60,13 +63,22 @@ module Logga
60
63
 
61
64
  def author_data
62
65
  data = Hash(log_receiver.try(:author) || try(:author)).with_indifferent_access
66
+
63
67
  {
64
68
  author_id: data[:id],
65
- author_type: data[:type],
66
- author_name: data[:name]
69
+ author_name: data[:name],
70
+ author_type: data[:type]
67
71
  }
68
72
  end
69
73
 
74
+ def config_excluded_fields
75
+ Logga.configuration.excluded_fields
76
+ end
77
+
78
+ def config_excluded_suffixes
79
+ Logga.configuration.excluded_suffixes
80
+ end
81
+
70
82
  def create_log_entry(entry)
71
83
  log_receiver&.log_entries&.create(entry)
72
84
  end
@@ -78,10 +90,7 @@ module Logga
78
90
  end
79
91
 
80
92
  def default_creation_log_body(record)
81
- [
82
- "#{titleized_model_class_name(record)} created",
83
- ("(#{record.state})" if record.try(:state))
84
- ].compact.join(" ")
93
+ "#{titleized_model_class_name(record)} created"
85
94
  end
86
95
 
87
96
  def default_change_log_body(record, field, _old_value, new_value)
@@ -100,19 +109,22 @@ module Logga
100
109
  default_change_log_body(record, field, old_value, new_value)
101
110
  }
102
111
  changes.inject([]) do |result, (field, (old_value, new_value))|
103
- result << log_fields.fetch(field.to_sym, body_generator).call(self, field, old_value, new_value)
112
+ result << fields.fetch(field.to_sym, body_generator).call(self, field, old_value, new_value)
104
113
  end.compact.join("\n")
105
114
  end
106
115
 
107
116
  def reject_change?(key)
108
- EXCLUDED_KEYS.include?(key.to_sym) ||
109
- (!log_fields.include?(key.to_sym) &&
110
- (excluded_fields.include?(key.to_sym) ||
111
- EXCLUDED_KEYS_SUFFIXES.any? { |suffix| key.to_s.end_with?(suffix.to_s) }))
117
+ sym_key = key.to_sym
118
+ return allowed_fields.exclude?(sym_key) if allowed_fields.present?
119
+
120
+ config_excluded_fields.include?(sym_key) ||
121
+ (fields.exclude?(sym_key) &&
122
+ (excluded_fields.include?(sym_key) ||
123
+ config_excluded_suffixes.any? { |suffix| key.to_s.end_with?(suffix.to_s) }))
112
124
  end
113
125
 
114
- def should_not_log?
115
- !log_receiver.respond_to?(:log_entries)
126
+ def should_log?
127
+ Logga.enabled? && log_receiver.respond_to?(:log_entries)
116
128
  end
117
129
 
118
130
  def titleized_model_class_name(record)
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Logga
4
+ class Config
5
+ attr_accessor :enabled, :excluded_fields, :excluded_suffixes
6
+
7
+ def initialize(enabled: true, excluded_fields: [], excluded_suffixes: [])
8
+ @enabled = enabled
9
+ @excluded_fields = excluded_fields
10
+ @excluded_suffixes = excluded_suffixes
11
+ end
12
+ end
13
+ end
data/lib/logga.rb CHANGED
@@ -3,11 +3,37 @@
3
3
  require "active_support"
4
4
  require "active_support/core_ext"
5
5
  require "active_support/concern"
6
- require_relative "logga/version"
6
+
7
7
  require_relative "logga/active_record"
8
+ require_relative "logga/config"
9
+ require_relative "logga/version"
8
10
 
9
11
  module Logga
10
12
  ActiveSupport.on_load(:active_record) do
11
13
  include Logga::ActiveRecord
12
14
  end
15
+
16
+ class << self
17
+ def configuration
18
+ @configuration ||= Config.new
19
+ end
20
+
21
+ def configure
22
+ yield(configuration)
23
+ end
24
+
25
+ # Switches Logga on or off
26
+ def enabled=(value)
27
+ configuration.enabled = value
28
+ end
29
+
30
+ # Returns `true` if Logga is on, `false` otherwise
31
+ def enabled?
32
+ !!configuration.enabled
33
+ end
34
+
35
+ def version
36
+ Logga::VERSION
37
+ end
38
+ end
13
39
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logga
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 4.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boxt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-23 00:00:00.000000000 Z
11
+ date: 2022-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,138 +16,40 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5.2'
20
- - - "~>"
19
+ version: '6'
20
+ - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '6.0'
22
+ version: '8'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '5.2'
30
- - - "~>"
29
+ version: '6'
30
+ - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '6.0'
32
+ version: '8'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: activesupport
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '5.2'
40
- - - "~>"
39
+ version: '6'
40
+ - - "<"
41
41
  - !ruby/object:Gem::Version
42
- version: '6.0'
42
+ version: '8'
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: '5.2'
50
- - - "~>"
49
+ version: '6'
50
+ - - "<"
51
51
  - !ruby/object:Gem::Version
52
- version: '6.0'
53
- - !ruby/object:Gem::Dependency
54
- name: boxt_ruby_style_guide
55
- requirement: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - '='
58
- - !ruby/object:Gem::Version
59
- version: 7.2.0
60
- type: :development
61
- prerelease: false
62
- version_requirements: !ruby/object:Gem::Requirement
63
- requirements:
64
- - - '='
65
- - !ruby/object:Gem::Version
66
- version: 7.2.0
67
- - !ruby/object:Gem::Dependency
68
- name: bundler
69
- requirement: !ruby/object:Gem::Requirement
70
- requirements:
71
- - - "~>"
72
- - !ruby/object:Gem::Version
73
- version: '2.1'
74
- type: :development
75
- prerelease: false
76
- version_requirements: !ruby/object:Gem::Requirement
77
- requirements:
78
- - - "~>"
79
- - !ruby/object:Gem::Version
80
- version: '2.1'
81
- - !ruby/object:Gem::Dependency
82
- name: byebug
83
- requirement: !ruby/object:Gem::Requirement
84
- requirements:
85
- - - "~>"
86
- - !ruby/object:Gem::Version
87
- version: '11.0'
88
- type: :development
89
- prerelease: false
90
- version_requirements: !ruby/object:Gem::Requirement
91
- requirements:
92
- - - "~>"
93
- - !ruby/object:Gem::Version
94
- version: '11.0'
95
- - !ruby/object:Gem::Dependency
96
- name: rake
97
- requirement: !ruby/object:Gem::Requirement
98
- requirements:
99
- - - "~>"
100
- - !ruby/object:Gem::Version
101
- version: '13.0'
102
- type: :development
103
- prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
- requirements:
106
- - - "~>"
107
- - !ruby/object:Gem::Version
108
- version: '13.0'
109
- - !ruby/object:Gem::Dependency
110
- name: rspec
111
- requirement: !ruby/object:Gem::Requirement
112
- requirements:
113
- - - "~>"
114
- - !ruby/object:Gem::Version
115
- version: '3.9'
116
- type: :development
117
- prerelease: false
118
- version_requirements: !ruby/object:Gem::Requirement
119
- requirements:
120
- - - "~>"
121
- - !ruby/object:Gem::Version
122
- version: '3.9'
123
- - !ruby/object:Gem::Dependency
124
- name: rspec-nc
125
- requirement: !ruby/object:Gem::Requirement
126
- requirements:
127
- - - "~>"
128
- - !ruby/object:Gem::Version
129
- version: '0.3'
130
- type: :development
131
- prerelease: false
132
- version_requirements: !ruby/object:Gem::Requirement
133
- requirements:
134
- - - "~>"
135
- - !ruby/object:Gem::Version
136
- version: '0.3'
137
- - !ruby/object:Gem::Dependency
138
- name: simplecov
139
- requirement: !ruby/object:Gem::Requirement
140
- requirements:
141
- - - "~>"
142
- - !ruby/object:Gem::Version
143
- version: '0.17'
144
- type: :development
145
- prerelease: false
146
- version_requirements: !ruby/object:Gem::Requirement
147
- requirements:
148
- - - "~>"
149
- - !ruby/object:Gem::Version
150
- version: '0.17'
52
+ version: '8'
151
53
  description: Extensions to ActiveRecord to log entries on model changes
152
54
  email:
153
55
  - developers@boxt.co.uk
@@ -161,11 +63,13 @@ files:
161
63
  - VERSION
162
64
  - lib/logga.rb
163
65
  - lib/logga/active_record.rb
66
+ - lib/logga/config.rb
164
67
  - lib/logga/version.rb
165
68
  homepage: https://github.com/boxt/logga
166
69
  licenses:
167
70
  - MIT
168
- metadata: {}
71
+ metadata:
72
+ rubygems_mfa_required: 'true'
169
73
  post_install_message:
170
74
  rdoc_options: []
171
75
  require_paths:
@@ -174,14 +78,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
174
78
  requirements:
175
79
  - - ">="
176
80
  - !ruby/object:Gem::Version
177
- version: '2.5'
81
+ version: '2.7'
178
82
  required_rubygems_version: !ruby/object:Gem::Requirement
179
83
  requirements:
180
84
  - - ">="
181
85
  - !ruby/object:Gem::Version
182
86
  version: '0'
183
87
  requirements: []
184
- rubygems_version: 3.1.4
88
+ rubygems_version: 3.3.7
185
89
  signing_key:
186
90
  specification_version: 4
187
91
  summary: ActiveRecord log entries on model changes