mirror of
https://github.com/aasm/aasm
synced 2023-03-27 23:22:41 -04:00
Introduces instance level skip validation option.
This commit is contained in:
parent
0ce55f2c78
commit
aa34bafe7c
5 changed files with 71 additions and 0 deletions
|
@ -740,6 +740,14 @@ class Job < ActiveRecord::Base
|
|||
end
|
||||
```
|
||||
|
||||
Also You can skip the validation at instance level with `some_event_name_without_validation!` method.
|
||||
With this you have the flexibility of having validation for all your transitions by default and then skip it wherever required.
|
||||
Please note that only state column will be updated as mentioned in the above example.
|
||||
|
||||
```ruby
|
||||
job.run_without_validation!
|
||||
```
|
||||
|
||||
If you want to make sure that the _AASM_ column for storing the state is not directly assigned,
|
||||
configure _AASM_ to not allow direct assignment, like this:
|
||||
|
||||
|
|
|
@ -133,6 +133,8 @@ module AASM
|
|||
aasm_fire_event(aasm_name, event, {:persist => false}, *args, &block)
|
||||
end
|
||||
|
||||
skip_instance_level_validation(event, name, aasm_name, klass)
|
||||
|
||||
# Create aliases for the event methods. Keep the old names to maintain backwards compatibility.
|
||||
if namespace?
|
||||
klass.send(:alias_method, "may_#{name}_#{namespace}?", "may_#{name}?")
|
||||
|
@ -248,5 +250,20 @@ module AASM
|
|||
end
|
||||
end
|
||||
|
||||
def skip_instance_level_validation(event, name, aasm_name, klass)
|
||||
# Overrides the skip_validation config for an instance (If skip validation is set to false in original config) and
|
||||
# restores it back to the original value after the event is fired.
|
||||
safely_define_method klass, "#{name}_without_validation!", ->(*args, &block) do
|
||||
original_config = AASM::StateMachineStore.fetch(self.class, true).machine(aasm_name).config.skip_validation_on_save
|
||||
begin
|
||||
AASM::StateMachineStore.fetch(self.class, true).machine(aasm_name).config.skip_validation_on_save = true unless original_config
|
||||
aasm(aasm_name).current_event = :"#{name}!"
|
||||
aasm_fire_event(aasm_name, event, {:persist => true}, *args, &block)
|
||||
ensure
|
||||
AASM::StateMachineStore.fetch(self.class, true).machine(aasm_name).config.skip_validation_on_save = original_config
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,4 +51,9 @@ ActiveRecord::Migration.suppress_messages do
|
|||
t.string "search"
|
||||
t.string "sync"
|
||||
end
|
||||
|
||||
ActiveRecord::Migration.create_table "instance_level_skip_validation_examples", :force => true do |t|
|
||||
t.string "state"
|
||||
t.string "some_string"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
class InstanceLevelSkipValidationExample < ActiveRecord::Base
|
||||
include AASM
|
||||
|
||||
aasm :state do
|
||||
state :new, :initial => true
|
||||
state :draft
|
||||
state :complete
|
||||
|
||||
event :set_draft do
|
||||
transitions from: :new, to: :draft
|
||||
end
|
||||
|
||||
event :complete do
|
||||
transitions from: %i[draft new], to: :complete
|
||||
end
|
||||
end
|
||||
|
||||
validates :some_string, presence: true
|
||||
end
|
|
@ -748,4 +748,26 @@ if defined?(ActiveRecord)
|
|||
expect { job.run }.to raise_error(AASM::InvalidTransition)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'testing the instance_level skip validation with _without_validation method' do
|
||||
let(:example) do
|
||||
obj = InstanceLevelSkipValidationExample.new(state: 'new')
|
||||
obj.save(validate: false)
|
||||
obj
|
||||
end
|
||||
|
||||
it 'should be able to change the state with invalid record' do
|
||||
expect(example.valid?).to be_falsey
|
||||
expect(example.complete!).to be_falsey
|
||||
expect(example.complete_without_validation!).to be_truthy
|
||||
expect(example.state).to eq('complete')
|
||||
end
|
||||
|
||||
it 'shouldn\'t affect the behaviour of existing method after calling _without_validation! method' do
|
||||
expect(example.set_draft!).to be_falsey
|
||||
expect(example.set_draft_without_validation!).to be_truthy
|
||||
expect(example.state).to eq('draft')
|
||||
expect(example.complete!).to be_falsey
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue