Module: AfterCommitEverywhere
- Defined in:
- lib/after_commit_everywhere.rb,
lib/after_commit_everywhere/wrap.rb,
lib/after_commit_everywhere/version.rb
Overview
Module allowing to use ActiveRecord transactional callbacks outside of ActiveRecord models, literally everywhere in your application.
Include it to your classes (e.g. your base service object class or whatever)
Defined Under Namespace
Classes: NotInTransaction, Wrap
Constant Summary collapse
- VERSION =
'0.1.2'
Class Method Summary collapse
Instance Method Summary collapse
-
#after_commit(connection: ActiveRecord::Base.connection, &callback) ⇒ Object
Runs
callbackafter successful commit of outermost transaction for databaseconnection. -
#after_rollback(connection: ActiveRecord::Base.connection, &callback) ⇒ Object
Runs
callbackafter rolling back of transaction or savepoint (if declared in nested transaction) for databaseconnection. -
#before_commit(connection: ActiveRecord::Base.connection, &callback) ⇒ Object
Runs
callbackbefore committing of outermost transaction forconnection.
Class Method Details
.register_callback(connection:, name:, no_tx_action:, callback:) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/after_commit_everywhere.rb', line 73 def register_callback(connection:, name:, no_tx_action:, callback:) raise ArgumentError, "Provide callback to #{name}" unless callback unless in_transaction?(connection) case no_tx_action when :warn_and_execute warn "#{name}: No transaction open. Executing callback immediately." return callback.call when :execute return callback.call when :exception raise NotInTransaction, "#{name} is useless outside transaction" end end wrap = Wrap.new(connection: connection, "#{name}": callback) connection.add_transaction_record(wrap) end |
Instance Method Details
#after_commit(connection: ActiveRecord::Base.connection, &callback) ⇒ Object
Runs callback after successful commit of outermost transaction for database connection.
If called outside transaction it will execute callback immediately.
23 24 25 26 27 28 29 30 |
# File 'lib/after_commit_everywhere.rb', line 23 def after_commit(connection: ActiveRecord::Base.connection, &callback) AfterCommitEverywhere.register_callback( connection: connection, name: __callee__, callback: callback, no_tx_action: :execute, ) end |
#after_rollback(connection: ActiveRecord::Base.connection, &callback) ⇒ Object
Runs callback after rolling back of transaction or savepoint (if declared in nested transaction) for database connection.
Caveat: do not raise ActivRecord::Rollback in nested transaction block! See api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html#module-ActiveRecord::Transactions::ClassMethods-label-Nested+transactions
63 64 65 66 67 68 69 70 |
# File 'lib/after_commit_everywhere.rb', line 63 def after_rollback(connection: ActiveRecord::Base.connection, &callback) AfterCommitEverywhere.register_callback( connection: connection, name: __callee__, callback: callback, no_tx_action: :exception, ) end |
#before_commit(connection: ActiveRecord::Base.connection, &callback) ⇒ Object
Runs callback before committing of outermost transaction for connection.
If called outside transaction it will execute callback immediately.
Available only since Ruby on Rails 5.0. See github.com/rails/rails/pull/18936
41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/after_commit_everywhere.rb', line 41 def before_commit(connection: ActiveRecord::Base.connection, &callback) if ActiveRecord::VERSION::MAJOR < 5 raise NotImplementedError, "#{__callee__} works only with Rails 5.0+" end AfterCommitEverywhere.register_callback( connection: connection, name: __callee__, callback: callback, no_tx_action: :warn_and_execute, ) end |