Module: ValidatesOverlap::RescueExclusionViolation
- Defined in:
- lib/validates_overlap/rescue_exclusion_violation.rb
Overview
Opt-in companion to the exclusion constraint (see MigrationHelpers): in the race window the validator cannot see, the constraint raises — this concern rescues that and turns it into a normal validation failure: save returns false with errors populated, save! raises ActiveRecord::RecordInvalid.
NOTE: a statement error aborts the innermost database transaction, so when the caller already has a joinable transaction open, save runs in its own savepoint (requires_new) with the rescue OUTSIDE it — otherwise the rescue would leave the caller's transaction in the aborted state. (The same pattern the Rails guides document for rescuing RecordNotUnique.) In every other situation the wrapper must NOT be added: ActiveRecord's own save transaction already contains the error there, and an extra wrapper at top level makes the save transaction JOIN it — silently swallowing the rollback a halted callback (throw :abort) relies on.
Example:
class Meeting < ActiveRecord::Base
validates :starts_at, :ends_at, overlap: { scope: :user_id }
include ValidatesOverlap::RescueExclusionViolation
end
Instance Method Summary collapse
Instance Method Details
#save ⇒ Object
23 24 25 26 27 28 29 |
# File 'lib/validates_overlap/rescue_exclusion_violation.rb', line 23 def save(...) contain_exclusion_violation { super } rescue ActiveRecord::StatementInvalid => e raise unless ValidatesOverlap.exclusion_violation?(e) add_overlap_error false end |
#save! ⇒ Object
31 32 33 34 35 36 37 |
# File 'lib/validates_overlap/rescue_exclusion_violation.rb', line 31 def save!(...) contain_exclusion_violation { super } rescue ActiveRecord::StatementInvalid => e raise unless ValidatesOverlap.exclusion_violation?(e) add_overlap_error raise ActiveRecord::RecordInvalid, self end |