Class: RuboCop::Cop::DevDoc::Rails::BangSaveInTransaction
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::DevDoc::Rails::BangSaveInTransaction
- Extended by:
- AutoCorrector
- Defined in:
- lib/rubocop/cop/dev_doc/rails/bang_save_in_transaction.rb
Overview
Flag bare (return-value-discarded) ‘save`/`update`/`create` calls inside a `transaction` block.
## Rationale Inside a transaction a non-bang ‘save` / `update` / `create` whose return value is discarded is almost always a bug. The transaction does not roll back on a `false` return — execution continues as if the write succeeded, silently producing inconsistent data.
Checking the return value (as a condition or assignment) is allowed, as is the bang form. Only the bare-statement form is flagged.
❌ silent failure — transaction does not roll back
ApplicationRecord.transaction do
@order.save
create_child_records(...)
end
✔️ return value gated — ok
ApplicationRecord.transaction do
if @order.save
create_child_records(...)
end
end
✔️ bang method — raises on failure, rolls back
ApplicationRecord.transaction do
@order.save!
create_child_records(...)
end
Constant Summary collapse
- MSG =
'Use `%<bang>s` inside a `transaction` block, or check its return value. ' \ 'A non-bang call whose return value is discarded does not roll back the transaction on failure.'.freeze
- FLAGGED_METHODS =
%i[save update create].freeze
- CONSUMING_PARENT_TYPES =
Node types whose parent always means the return value is consumed.
%i[ and or return send csend lvasgn ivasgn cvasgn gvasgn casgn masgn array hash pair ].freeze
Instance Method Summary collapse
Instance Method Details
#on_send(node) ⇒ Object
77 78 79 80 81 82 83 84 85 86 |
# File 'lib/rubocop/cop/dev_doc/rails/bang_save_in_transaction.rb', line 77 def on_send(node) return unless FLAGGED_METHODS.include?(node.method_name) return unless inside_transaction?(node) return if return_value_used?(node) bang = :"#{node.method_name}!" add_offense(node.loc.selector, message: format(MSG, bang: bang)) do |corrector| corrector.replace(node.loc.selector, bang.to_s) end end |