ar_after_transaction 0.5.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Readme.md +46 -32
- data/lib/ar_after_transaction/version.rb +4 -2
- data/lib/ar_after_transaction.rb +55 -52
- metadata +15 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0cc72b7f26b842b9adfedb004133d2cc0748e0783b0fdfeb0aebe9e4c52f8b3a
|
4
|
+
data.tar.gz: c61ca0e181cc2a4eaacdb45b63aab20dc77bd7af72dcb066735adce2f989944b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5402cb5c03bbf9d67a8a2da4e30dde24c191e8ec403a8f4a0084d95a5d6d46f9d658cf3903f21f2947e51113df2a13eae51393bf6e8a9730e3bd8126a93cabc
|
7
|
+
data.tar.gz: 4e6556949152666f978bf152ac5c4c830dfbbaa4cb3a36da6004a4ec8a2273a989476116377ec81c3f58e4710265da911eaf2debf5565ca21718c6443c3904ca
|
data/Readme.md
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
[![Gem Version](https://badge.fury.io/rb/ar_after_transaction.png)](http://badge.fury.io/rb/ar_after_transaction)
|
2
|
-
|
3
|
-
[![Dependency Status](https://gemnasium.com/grosser/ar_after_transaction.png)](https://gemnasium.com/grosser/ar_after_transaction)
|
2
|
+
![CI](https://github.com/grosser/ar_after_transaction/workflows/CI/badge.svg)
|
4
3
|
|
5
4
|
Do something only after the currently open transactions have finished.
|
6
5
|
|
@@ -9,36 +8,44 @@ Normally everything gets rolled back when a transaction fails, but you cannot ro
|
|
9
8
|
Install
|
10
9
|
=======
|
11
10
|
|
12
|
-
|
11
|
+
```bash
|
12
|
+
gem install ar_after_transaction
|
13
|
+
```
|
13
14
|
|
14
15
|
|
15
16
|
Usage
|
16
17
|
=====
|
18
|
+
|
17
19
|
### just-in-time callbacks
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def oops
|
29
|
-
raise "do the rolback!"
|
30
|
-
end
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
class User
|
23
|
+
after_create :do_stuff, :oops
|
24
|
+
|
25
|
+
def do_stuff
|
26
|
+
after_transaction do
|
27
|
+
send_an_email # cannot be rolled back
|
31
28
|
end
|
29
|
+
comments.create(...) # will be rolled back
|
30
|
+
end
|
31
|
+
|
32
|
+
def oops
|
33
|
+
raise "do the rolback!"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
```
|
32
37
|
|
33
38
|
### General 'this should be rolled back when in a transaction' code like jobs
|
34
39
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
40
|
+
```ruby
|
41
|
+
class Resque
|
42
|
+
def revertable_enqueue(*args)
|
43
|
+
ActiveRecord::Base.after_transaction do
|
44
|
+
enqueue(*args)
|
41
45
|
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
```
|
42
49
|
|
43
50
|
### When not in a transaction
|
44
51
|
after_transaction will perform the given block immediately
|
@@ -47,25 +54,31 @@ after_transaction will perform the given block immediately
|
|
47
54
|
after_transaction assumes zero open transactions.<br/>
|
48
55
|
If you use transactional fixtures you should change it in test mode.
|
49
56
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
57
|
+
`Rspec:`
|
58
|
+
```ruby
|
59
|
+
# spec/rails_helper.rb
|
60
|
+
config.before(:suite) do
|
61
|
+
ActiveRecord::Base.normally_open_transactions = 1
|
62
|
+
end
|
63
|
+
```
|
54
64
|
|
55
65
|
### Rails 3: after_commit hook can replace the first usage example:
|
56
66
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
67
|
+
```ruby
|
68
|
+
class User
|
69
|
+
after_commit :send_an_email on: :create
|
70
|
+
after_create :do_stuff, :oops
|
71
|
+
...
|
72
|
+
end
|
73
|
+
```
|
62
74
|
|
63
75
|
Alternative
|
64
76
|
===========
|
77
|
+
|
65
78
|
Rails 3+
|
66
79
|
- basic support is built in, use it if you can!
|
67
80
|
- `after_commit :foo`
|
68
|
-
- `after_commit :bar, :
|
81
|
+
- `after_commit :bar, on: :create / :update`
|
69
82
|
- [after_commit everywhere](https://dev.to/evilmartians/rails-aftercommit-everywhere--4j9g)
|
70
83
|
|
71
84
|
|
@@ -86,6 +99,7 @@ Authors
|
|
86
99
|
- [Michael Wu](https://github.com/michaelmwu)
|
87
100
|
- [C.W.](https://github.com/compwron)
|
88
101
|
- [Ben Weintraub](https://github.com/benweint)
|
102
|
+
- [Vladimir Temnikov](https://github.com/vladimirtemnikov)
|
89
103
|
|
90
104
|
[Michael Grosser](http://grosser.it)<br/>
|
91
105
|
michael@grosser.it<br/>
|
data/lib/ar_after_transaction.rb
CHANGED
@@ -1,72 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_record'
|
2
4
|
require 'ar_after_transaction/version'
|
3
5
|
|
4
6
|
module ARAfterTransaction
|
5
7
|
module ClassMethods
|
6
|
-
def self.extended( base )
|
7
|
-
base.class_eval do
|
8
|
-
class << self
|
9
|
-
alias_method :transaction_without_after, :transaction
|
10
|
-
alias_method :transaction, :transaction_with_after
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def transaction_with_after(*args)
|
16
|
-
clean = true
|
17
|
-
transaction_without_after(*args) do
|
18
|
-
begin
|
19
|
-
yield
|
20
|
-
rescue ActiveRecord::Rollback
|
21
|
-
clean = false
|
22
|
-
raise
|
23
|
-
end
|
24
|
-
end
|
25
|
-
rescue Exception
|
26
|
-
clean = false
|
27
|
-
raise
|
28
|
-
ensure
|
29
|
-
unless transactions_open?
|
30
|
-
callbacks = delete_after_transaction_callbacks
|
31
|
-
callbacks.each(&:call) if clean
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
8
|
def after_transaction(&block)
|
36
|
-
|
37
|
-
connection.after_transaction_callbacks ||= []
|
38
|
-
connection.after_transaction_callbacks << block
|
39
|
-
else
|
40
|
-
yield
|
41
|
-
end
|
9
|
+
connection.after_transaction(&block)
|
42
10
|
end
|
43
11
|
|
44
12
|
def normally_open_transactions
|
45
|
-
|
13
|
+
connection.normally_open_transactions ||= 0
|
46
14
|
end
|
47
15
|
|
48
|
-
|
49
|
-
@@normally_open_transactions = value
|
50
|
-
end
|
16
|
+
delegate :normally_open_transactions=, to: :connection
|
51
17
|
|
52
18
|
private
|
53
19
|
|
54
20
|
def transactions_open?
|
55
|
-
|
56
|
-
return false unless pool && pool.active_connection?
|
57
|
-
connection.open_transactions > normally_open_transactions
|
58
|
-
end
|
59
|
-
|
60
|
-
def delete_after_transaction_callbacks
|
61
|
-
result = connection.after_transaction_callbacks || []
|
62
|
-
connection.after_transaction_callbacks = []
|
63
|
-
result
|
21
|
+
connection.send :transactions_open?
|
64
22
|
end
|
65
23
|
end
|
66
24
|
|
67
25
|
module InstanceMethods
|
68
26
|
def after_transaction(&block)
|
69
|
-
self.class.after_transaction(&block)
|
27
|
+
self.class.connection.after_transaction(&block)
|
70
28
|
end
|
71
29
|
end
|
72
30
|
end
|
@@ -76,10 +34,55 @@ module ARAfterTransactionConnection
|
|
76
34
|
base.class_eval do
|
77
35
|
attr_accessor :normally_open_transactions
|
78
36
|
attr_accessor :after_transaction_callbacks
|
37
|
+
|
38
|
+
alias_method :transaction_without_after, :transaction
|
39
|
+
alias_method :transaction, :transaction_with_after
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def transaction_with_after(**args)
|
44
|
+
clean = true
|
45
|
+
transaction_without_after(**args) do
|
46
|
+
yield
|
47
|
+
rescue ActiveRecord::Rollback
|
48
|
+
clean = false
|
49
|
+
raise
|
50
|
+
end
|
51
|
+
rescue StandardError
|
52
|
+
clean = false
|
53
|
+
raise
|
54
|
+
ensure
|
55
|
+
unless transactions_open?
|
56
|
+
callbacks = delete_after_transaction_callbacks
|
57
|
+
callbacks.each(&:call) if clean
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def after_transaction(&block)
|
62
|
+
if transactions_open?
|
63
|
+
self.after_transaction_callbacks ||= []
|
64
|
+
self.after_transaction_callbacks << block
|
65
|
+
else
|
66
|
+
yield
|
79
67
|
end
|
80
68
|
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def transactions_open?
|
73
|
+
return false unless active?
|
74
|
+
|
75
|
+
self.normally_open_transactions ||= 0
|
76
|
+
open_transactions > normally_open_transactions
|
77
|
+
end
|
78
|
+
|
79
|
+
def delete_after_transaction_callbacks
|
80
|
+
result = after_transaction_callbacks || []
|
81
|
+
self.after_transaction_callbacks = []
|
82
|
+
result
|
83
|
+
end
|
81
84
|
end
|
82
85
|
|
83
|
-
ActiveRecord::Base.
|
84
|
-
ActiveRecord::Base.
|
85
|
-
ActiveRecord::ConnectionAdapters::AbstractAdapter.
|
86
|
+
ActiveRecord::Base.extend ARAfterTransaction::ClassMethods
|
87
|
+
ActiveRecord::Base.include ARAfterTransaction::InstanceMethods
|
88
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.include ARAfterTransactionConnection
|
metadata
CHANGED
@@ -1,37 +1,37 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ar_after_transaction
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Grosser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.2.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '7.1'
|
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:
|
29
|
+
version: 5.2.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '7.1'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
34
|
+
name: bump
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
@@ -45,7 +45,7 @@ dependencies:
|
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
48
|
+
name: rails
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - ">="
|
@@ -78,14 +78,14 @@ dependencies:
|
|
78
78
|
requirements:
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
81
|
+
version: '3'
|
82
82
|
type: :development
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
88
|
+
version: '3'
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: sqlite3
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -101,7 +101,7 @@ dependencies:
|
|
101
101
|
- !ruby/object:Gem::Version
|
102
102
|
version: '0'
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
|
-
name:
|
104
|
+
name: wwtd
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
106
106
|
requirements:
|
107
107
|
- - ">="
|
@@ -135,15 +135,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
135
135
|
requirements:
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 2.
|
138
|
+
version: 2.6.0
|
139
139
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
140
|
requirements:
|
141
141
|
- - ">="
|
142
142
|
- !ruby/object:Gem::Version
|
143
143
|
version: '0'
|
144
144
|
requirements: []
|
145
|
-
|
146
|
-
rubygems_version: 2.7.6
|
145
|
+
rubygems_version: 3.1.6
|
147
146
|
signing_key:
|
148
147
|
specification_version: 4
|
149
148
|
summary: Execute irreversible actions only when transactions are not rolled back
|