omg-audit-group 0.1.2 → 0.1.4

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: c0c376f111fedecd658dac64a321545b036c3a672cb8a7b4e8f6c443a90fbe74
4
- data.tar.gz: d8c9fa53d36b22ef3b57c41bf11a73131e6c90ac8e011c45604b155025db7251
3
+ metadata.gz: c2103693c9d639bfce07ecae254b8df32a5571ed8084a141aa3b7d072ea62632
4
+ data.tar.gz: 8b49dfc610cacdf906fa910414064ad4cec032a14809512111e22c3f290c5e38
5
5
  SHA512:
6
- metadata.gz: 50c5f348251c2c296f3f778eb3704992b2c459926c0f4814e8a13cba5906a90349844037316aa682840518ca990312d5317ab2efaef40423fd5c41f27cb5d5fa
7
- data.tar.gz: 9f49b04443555acd365e821367d378b63e832a76e16b8cf86d82a5dcfcca2d4356323330fe67712d40820676c8cda8f935d5d92547a225cc82847486a73bea09
6
+ metadata.gz: 11d2bd4799f4680ca1b20487e64cd90292a2993c3741bceaa4301fc2adc273de765a346360fbc35268f078b18a334256571f59e7898b227918c4ef743a2aff57
7
+ data.tar.gz: 910a307b97833b1542ec839bb9b20c5cbc9732bbeb316accd78140a8e7d102894240ddf2e3227cbc2ee8e79172514eecf07048863dbd579cec120ee02deeb22c
data/lib/audit_group.rb CHANGED
@@ -1,60 +1,141 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support/all'
4
3
  require 'audited'
5
4
 
6
5
  class AuditGroup
7
- VERSION = '0.1.2'
6
+ VERSION = '0.1.4'
8
7
 
9
- attr_reader :block, :request_uuid
10
-
11
- delegate :current, :unset_request_uuid, to: :class
8
+ class LockError < StandardError
9
+ def initialize
10
+ super('Request is locked and cannot be run again. If you want to add operations to an existing request_uuid, create a new instance')
11
+ end
12
+ end
12
13
 
13
14
  class << self
14
15
  attr_accessor :current
15
16
 
16
- delegate :request_uuid, :audits, to: :current
17
-
17
+ ##
18
+ # Updates `audited` gem to make every operation use the same `request_uuid`.
19
+ #
20
+ # @param request_uuid [String] The `request_uuid` to use for all operations within the block.
18
21
  def set_request_uuid(request_uuid = SecureRandom.uuid)
19
22
  Audited.store[:current_request_uuid] = request_uuid
20
23
  end
21
24
 
25
+ ##
26
+ # Resets `audited` gem to generate a new `request_uuid` for each operation.
22
27
  def unset_request_uuid
23
28
  Audited.store.delete(:current_request_uuid)
24
29
  end
25
30
 
31
+ ##
32
+ # Clears out any current `request_uuid` or AuditGroup request.
26
33
  def reset
27
34
  unset_request_uuid
28
35
  @current = nil
29
36
  end
30
37
 
31
- def request(&block)
32
- raise ArgumentError, 'No block given and no active group' unless block_given?
38
+ ##
39
+ # Creates a new AuditGroup and runs operations to be all given the same `request_uuid`
40
+ #
41
+ # @yield operations whose audits should be associated with the same request_uuid.
42
+ def request(dry_run: false, &block)
43
+ new(dry_run: dry_run).request(&block)
44
+ end
45
+
46
+ def request_uuid
47
+ current.request_uuid
48
+ end
33
49
 
34
- new.request(&block)
50
+ def audits
51
+ current.audits
35
52
  end
36
53
  end
37
54
 
38
- def initialize(request_uuid = SecureRandom.uuid)
55
+ attr_reader :block, :request_uuid, :dry_run, :locked
56
+
57
+ ##
58
+ # Creates a new AuditGroup instance and updates `AuditGroup.current` to it.
59
+ #
60
+ # @param request_uuid [String] What all audits within the group will have assigned as their request_uuid.
61
+ # Useful if you want to group additional operations under a `request_uuid` that already exists in the DB.
62
+ # @param dry_run [Boolean] If true, the transaction will be rolled back after the block is executed.
63
+ # @yield operations whose audits should be associated with the same request_uuid.
64
+ def initialize(request_uuid = SecureRandom.uuid, dry_run: false, &block)
39
65
  @request_uuid = request_uuid
66
+ @dry_run = dry_run
67
+ @locked = false
68
+
40
69
  self.class.current = self
70
+
71
+ request(&block) if block_given?
41
72
  end
42
73
 
74
+ ##
75
+ # Sets the `request_uuid` used by the `audited` store, runs the passed in block, then clears the `request_uuid`.
76
+ # Subsequent `request` calls will also be given the same `request_uuid`.
77
+ #
78
+ # @yield operations whose audits should be associated with the same request_uuid.
79
+ # @return [AuditGroup] itself
43
80
  def request(&block)
81
+ raise ArgumentError, 'No block given' unless block_given?
82
+ raise LockError if locked?
83
+
44
84
  set_request_uuid
45
85
 
46
- block.call if block.present?
86
+ if dry_run?
87
+ ActiveRecord::Base.transaction do
88
+ block.call
89
+
90
+ # Calls .to_a to keep records in memory after rollback
91
+ @audits = audits.to_a
92
+
93
+ raise ActiveRecord::Rollback
94
+ end
95
+ else
96
+ block.call
97
+ end
98
+
99
+ lock!
47
100
 
48
101
  self
49
102
  ensure
50
103
  unset_request_uuid
51
104
  end
52
105
 
53
- def set_request_uuid
54
- self.class.set_request_uuid(request_uuid)
106
+ ##
107
+ # @return [Boolean] whether this request is a dry run and will therefore not persist changes.
108
+ def dry_run?
109
+ dry_run
110
+ end
111
+
112
+ ##
113
+ # @return [Boolean] whether this request has already been run and is therefore locked.
114
+ def locked?
115
+ locked
55
116
  end
56
117
 
118
+ def lock!
119
+ @locked = true
120
+ end
121
+
122
+ ##
123
+ # Returns all associated audits. If `dry_run` is true, these will not be persistent in DB.
124
+ #
125
+ # @return [ActiveRecord::Relation] all audits associated with the request.
57
126
  def audits
58
127
  Audited::Audit.where(request_uuid: request_uuid)
59
128
  end
129
+
130
+ def set_request_uuid
131
+ self.class.set_request_uuid(request_uuid)
132
+ end
133
+
134
+ def unset_request_uuid
135
+ self.class.unset_request_uuid
136
+ end
137
+
138
+ def current
139
+ self.class.current
140
+ end
60
141
  end
metadata CHANGED
@@ -1,35 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omg-audit-group
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Greenfield
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-08 00:00:00.000000000 Z
11
+ date: 2024-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activesupport
14
+ name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '6.0'
19
+ version: '5.2'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '8.0'
22
+ version: '7.2'
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: '6.0'
29
+ version: '5.2'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '8.0'
32
+ version: '7.2'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: audited
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -58,19 +58,12 @@ executables: []
58
58
  extensions: []
59
59
  extra_rdoc_files: []
60
60
  files:
61
- - ".gitignore"
62
- - ".rspec"
63
- - README.md
64
- - Rakefile
65
- - audit_group.gemspec
66
61
  - lib/audit_group.rb
67
- - spec/audit_group_spec.rb
68
- - spec/spec_helper.rb
69
- homepage: https://github.com/omgreenfield/omg-util/tree/main/audit_group
62
+ homepage: https://github.com/omgreenfield/audit-group
70
63
  licenses:
71
64
  - MIT
72
65
  metadata:
73
- homepage_uri: https://github.com/omgreenfield/omg-util/tree/main/audit_group
66
+ homepage_uri: https://github.com/omgreenfield/audit-group
74
67
  rubygems_mfa_required: 'true'
75
68
  post_install_message:
76
69
  rdoc_options: []
@@ -80,14 +73,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
80
73
  requirements:
81
74
  - - ">="
82
75
  - !ruby/object:Gem::Version
83
- version: 2.7.0
76
+ version: 2.3.0
84
77
  required_rubygems_version: !ruby/object:Gem::Requirement
85
78
  requirements:
86
79
  - - ">="
87
80
  - !ruby/object:Gem::Version
88
81
  version: '0'
89
82
  requirements: []
90
- rubygems_version: 3.5.10
83
+ rubygems_version: 3.5.17
91
84
  signing_key:
92
85
  specification_version: 4
93
86
  summary: Groups transactions from the `audited` gem into a single request_uuid
data/.gitignore DELETED
@@ -1,12 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- sandbox.md
10
-
11
- # rspec failure tracking
12
- .rspec_status
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/README.md DELETED
@@ -1,98 +0,0 @@
1
- # AuditGroup
2
-
3
- Group ActiveRecord operations together by assigning all of their audits the same `request_uuid`.
4
-
5
- ## TODO
6
-
7
- - [ ] Add `rails` as dependency instead of `active_support`
8
- - [ ] Add `dry_run` method
9
-
10
- ## Requirements
11
-
12
- - [Audited](https://github.com/collectiveidea/audited) gem
13
-
14
- ## Installation
15
-
16
- ### From RubyGems.org
17
-
18
- #### Globally
19
-
20
- ```sh
21
- gem i omg-audit-group
22
- ```
23
-
24
- #### In `Gemfile`
25
-
26
- ```ruby
27
- gem 'omg-audit-group'
28
- ```
29
-
30
- ### Testing locally
31
- ```sh
32
- # Build gem
33
- rake build
34
-
35
- # Install gem
36
- ## From this directory
37
- rake install
38
-
39
- ## From other directory
40
- gem i -l /path/to/this/folder/omg-audit-group-0.1.0.gem
41
- ```
42
-
43
- ## Usage
44
-
45
- For convenience, the following operations are delegated from the `AuditGroup` module to the `AuditGroup::Request` class:
46
-
47
- - `new`
48
- - `request`
49
- - `current`
50
- - `request_uuid`
51
- - `audits`
52
-
53
- ### Using class methods
54
-
55
- ```ruby
56
- # Group operations under the same request_uuid
57
- AuditGroup.request { perform_some_operations }
58
-
59
- # View the last request_uuid
60
- AuditGroup.request_uuid
61
-
62
- # View the audits from the last request
63
- AuditGroup.audits
64
- ```
65
-
66
- ### Saving Request object for later use
67
-
68
- ```ruby
69
- # Group operations under the same request_uuid
70
- request = AuditGroup.request { perform_some_operations }
71
-
72
- # View the last request_uuid
73
- request.request_uuid
74
-
75
- # View the audits from the last request
76
- request.audits
77
- ```
78
-
79
- ### Instantiating a group
80
-
81
- You can also create separate `AuditGroup::Request` objects to reuse.
82
-
83
- ```ruby
84
- group = AuditGroup.new
85
- group.request { perform_some_operations }
86
- ...
87
- group.request { perform_more_operations }
88
- group.audits
89
- ```
90
-
91
- ## Running tests
92
-
93
- ```ruby
94
- rspec
95
-
96
- # or
97
- bundle exec rspec
98
- ```
data/Rakefile DELETED
@@ -1,17 +0,0 @@
1
- require_relative 'lib/audit_group'
2
-
3
- require 'rake'
4
-
5
- task :spec do
6
- sh 'bundle exec rspec'
7
- end
8
-
9
- task :build do
10
- sh 'gem build audit_group.gemspec'
11
- end
12
-
13
- task :push do
14
- sh "gem push omg-audit-group-#{AuditGroup::VERSION}.gem"
15
- end
16
-
17
- task :publish => :push
data/audit_group.gemspec DELETED
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'lib/audit_group'
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = 'omg-audit-group'
7
- spec.version = AuditGroup::VERSION
8
- spec.authors = ['Matthew Greenfield']
9
- spec.email = ['mattgreenfield1@gmail.com']
10
-
11
- spec.summary = 'Groups transactions from the `audited` gem into a single request_uuid'
12
- spec.description = 'Create, update, and delete records within a block, assign ' \
13
- 'the same request_uuid to them, and be able to easily view ' \
14
- 'and undo them'
15
-
16
- spec.homepage = 'https://github.com/omgreenfield/omg-util/tree/main/audit_group'
17
- spec.license = 'MIT'
18
- spec.required_ruby_version = '>= 2.7.0'
19
-
20
- spec.metadata['homepage_uri'] = spec.homepage
21
- spec.metadata['rubygems_mfa_required'] = 'true'
22
-
23
- spec.files = Dir.chdir(__dir__) do
24
- `git ls-files -z`.split("\x0").reject do |f|
25
- (File.expand_path(f) == __FILE__) ||
26
- f.start_with?(*%w[spec/.git .github Gemfile])
27
- end
28
- end
29
- spec.require_paths = ['lib']
30
-
31
- spec.add_dependency 'activesupport', '>= 6.0', '< 8.0'
32
- spec.add_dependency 'audited', '>= 4.9', '< 6.0'
33
- end
@@ -1,108 +0,0 @@
1
- RSpec.describe AuditGroup do
2
- describe 'class methods' do
3
- describe '.current' do
4
- it 'returns the last request created' do
5
- request = described_class.request {}
6
- expect(described_class.current).to eq(request)
7
- end
8
- end
9
-
10
- describe '.set_request_uuid' do
11
- it "sets the Audit store's current_request_uuid" do
12
- described_class.set_request_uuid('123')
13
- expect(Audited.store[:current_request_uuid]).to eq('123')
14
-
15
- described_class.set_request_uuid
16
- expect(Audited.store[:current_request_uuid]).to match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/)
17
- end
18
- end
19
-
20
- describe '.unset_request_uuid' do
21
- it "resets the Audit store's current_request_uuid" do
22
- Audited.store[:current_request_uuid] = '123'
23
- described_class.unset_request_uuid
24
- expect(Audited.store[:current_request_uuid]).to be_nil
25
- end
26
- end
27
-
28
- describe '.reset' do
29
- it 'unsets the request_uuid and current request' do
30
- described_class.set_request_uuid('123')
31
- described_class.current = 'some request'
32
-
33
- expect(Audited.store[:current_request_uuid]).to eq('123')
34
- expect(described_class.current).to eq('some request')
35
-
36
- described_class.reset
37
-
38
- expect(Audited.store[:current_request_uuid]).to be_nil
39
- expect(described_class.current).to be_nil
40
- end
41
- end
42
-
43
- describe '.request' do
44
- it 'raises an ArgumentError if no block is given and no active group' do
45
- expect { described_class.request }.to raise_error(ArgumentError, 'No block given and no active group')
46
- end
47
-
48
- it 'creates a new request if block is given' do
49
- expect { |block| described_class.request(&block) }.to yield_control
50
- end
51
- end
52
-
53
- describe '.request_uuid' do
54
- it 'delegates to current' do
55
- described_class.request {}
56
- expect(described_class.request_uuid).to eq(described_class.current.request_uuid)
57
- end
58
- end
59
-
60
- describe '.audits' do
61
- it 'delegates to current' do
62
- described_class.new('123')
63
- audited_audit = class_double('Audited::Audit').as_stubbed_const
64
- expect(audited_audit).to receive(:where).with(request_uuid: '123').and_return('some audits')
65
- expect(described_class.audits).to eq('some audits')
66
- end
67
- end
68
- end
69
-
70
- describe 'instance methods' do
71
- describe '#initialize' do
72
- it 'sets the request_uuid and current request' do
73
- request = described_class.new('123')
74
- expect(request.request_uuid).to eq('123')
75
- expect(described_class.current).to eq(request)
76
- end
77
- end
78
-
79
- describe '#request' do
80
- it 'sets the current_request_uuid, calls the block, then resets current_request_uuid' do
81
- request = described_class.new('123')
82
-
83
- request.request do
84
- expect(Audited.store[:current_request_uuid]).to eq('123')
85
- end
86
-
87
- expect(Audited.store[:current_request_uuid]).to be_nil
88
- end
89
- end
90
-
91
- describe '#set_request_uuid' do
92
- it 'delegates to class' do
93
- request = described_class.new('123')
94
- expect(request).to receive(:set_request_uuid)
95
- request.set_request_uuid
96
- end
97
- end
98
-
99
- describe '#audits' do
100
- it 'returns audits with request_uuid' do
101
- request = described_class.new('123')
102
- audited_audit = class_double('Audited::Audit').as_stubbed_const
103
- expect(audited_audit).to receive(:where).with(request_uuid: '123').and_return('some audits')
104
- expect(request.audits).to eq('some audits')
105
- end
106
- end
107
- end
108
- end
data/spec/spec_helper.rb DELETED
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'audit_group'
4
-
5
- RSpec.configure do |config|
6
- # Enable flags like --only-failures and --next-failure
7
- config.example_status_persistence_file_path = '.rspec_status'
8
-
9
- # Disable RSpec exposing methods globally on `Module` and `main`
10
- config.disable_monkey_patching!
11
-
12
- config.expect_with :rspec do |c|
13
- c.syntax = :expect
14
- end
15
- end