1
0
Fork 0
mirror of https://github.com/aasm/aasm synced 2023-03-27 23:22:41 -04:00

Implement whiny persistence so that transition! will raise by default, mirroring ActiveRecord's behavior.

@PragTob's suggestion from https://github.com/aasm/aasm/issues/262.
This commit is contained in:
Matthew Wilde 2016-05-16 16:09:03 -07:00
parent a26b2f3b03
commit 5739f92219
8 changed files with 98 additions and 18 deletions

View file

@ -23,6 +23,9 @@ module AASM
# don't store any new state if the model is invalid (in ActiveRecord)
configure :skip_validation_on_save, false
# raise if the model is invalid (in ActiveRecord)
configure :whiny_persistence, true
# use requires_new for nested transactions (in ActiveRecord)
configure :requires_new_transaction, true

View file

@ -9,7 +9,10 @@ module AASM
# for all persistence layers: create named scopes for each state
attr_accessor :create_scopes
# for ActiveRecord: don't store any new state if the model is invalid
# for ActiveRecord: when the model is invalid, true -> raise, false -> return false
attr_accessor :whiny_persistence
# for ActiveRecord: store the new state even if the model is invalid and return true
attr_accessor :skip_validation_on_save
# for ActiveRecord: use requires_new for nested transactions?

View file

@ -76,7 +76,12 @@ module AASM
self.save
end
success ? true : aasm_rollback(name, old_value)
unless success
aasm_rollback(name, old_value)
raise ActiveRecord::RecordInvalid.new(self) if aasm_whiny_persistence(name)
end
success
end
# Writes <tt>state</tt> to the state column, but does not persist it to the database
@ -130,6 +135,10 @@ module AASM
AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.skip_validation_on_save
end
def aasm_whiny_persistence(state_machine_name)
AASM::StateMachineStore.fetch(self.class, true).machine(state_machine_name).config.whiny_persistence
end
def aasm_write_attribute(state, name=:default)
write_attribute(self.class.aasm(name).attribute_name, aasm_raw_attribute_value(state, name))
end

View file

@ -1,3 +1,3 @@
module AASM
VERSION = "4.10.1"
VERSION = "5.0.0"
end

View file

@ -17,7 +17,7 @@ ActiveRecord::Migration.suppress_messages do
t.string "right"
end
%w(validators multiple_validators).each do |table_name|
%w(validators multiple_validators workers invalid_persistors multiple_invalid_persistors silent_persistors multiple_silent_persistors).each do |table_name|
ActiveRecord::Migration.create_table table_name, :force => true do |t|
t.string "name"
t.string "status"
@ -32,20 +32,6 @@ ActiveRecord::Migration.suppress_messages do
end
end
ActiveRecord::Migration.create_table "workers", :force => true do |t|
t.string "name"
t.string "status"
end
ActiveRecord::Migration.create_table "invalid_persistors", :force => true do |t|
t.string "name"
t.string "status"
end
ActiveRecord::Migration.create_table "multiple_invalid_persistors", :force => true do |t|
t.string "name"
t.string "status"
end
ActiveRecord::Migration.create_table "fathers", :force => true do |t|
t.string "aasm_state"
t.string "type"

View file

@ -0,0 +1,31 @@
require 'active_record'
class SilentPersistor < ActiveRecord::Base
include AASM
aasm :column => :status, :whiny_persistence => false do
state :sleeping, :initial => true
state :running
event :run do
transitions :to => :running, :from => :sleeping
end
event :sleep do
transitions :to => :sleeping, :from => :running
end
end
validates_presence_of :name
end
class MultipleSilentPersistor < ActiveRecord::Base
include AASM
aasm :left, :column => :status, :whiny_persistence => false do
state :sleeping, :initial => true
state :running
event :run do
transitions :to => :running, :from => :sleeping
end
event :sleep do
transitions :to => :sleeping, :from => :running
end
end
validates_presence_of :name
end

View file

@ -384,6 +384,30 @@ describe 'transitions with persistence' do
expect(validator).to be_valid
expect(validator).to be_sleeping
validator.name = nil
expect(validator).not_to be_valid
expect { validator.run! }.to raise_error(ActiveRecord::RecordInvalid)
expect(validator).to be_sleeping
validator.reload
expect(validator).not_to be_running
expect(validator).to be_sleeping
validator.name = 'another name'
expect(validator).to be_valid
expect(validator.run!).to be_truthy
expect(validator).to be_running
validator.reload
expect(validator).to be_running
expect(validator).not_to be_sleeping
end
it 'should not store states for invalid models silently if configured' do
validator = MultipleSilentPersistor.create(:name => 'name')
expect(validator).to be_valid
expect(validator).to be_sleeping
validator.name = nil
expect(validator).not_to be_valid
expect(validator.run!).to be_falsey

View file

@ -385,6 +385,30 @@ describe 'transitions with persistence' do
expect(validator).to be_valid
expect(validator).to be_sleeping
validator.name = nil
expect(validator).not_to be_valid
expect { validator.run! }.to raise_error(ActiveRecord::RecordInvalid)
expect(validator).to be_sleeping
validator.reload
expect(validator).not_to be_running
expect(validator).to be_sleeping
validator.name = 'another name'
expect(validator).to be_valid
expect(validator.run!).to be_truthy
expect(validator).to be_running
validator.reload
expect(validator).to be_running
expect(validator).not_to be_sleeping
end
it 'should not store states for invalid models silently if configured' do
validator = SilentPersistor.create(:name => 'name')
expect(validator).to be_valid
expect(validator).to be_sleeping
validator.name = nil
expect(validator).not_to be_valid
expect(validator.run!).to be_falsey