mirror of
https://github.com/aasm/aasm
synced 2023-03-27 23:22:41 -04:00
Fix ClassInvoker instantiating class twice
* I'm in the process of updating a rails app from rails 5.2 to rails 7. Currently the app is using AASM version 4.12.3. When I update to AASM version 5.x we start getting a failing spec in our app. The implementation uses the `after:` dsl and passes it a class. ``` ruby event :run_payment_create do transitions to: :active, after: Payment::GoCardless::Subscription::Charge end ``` The spec in our app expects that class to receive new 1 time with the args passed from after, but the spec is failing saying that `Payment::GoCardless::Subscription::Charge` received `.new` with the expected args twice. I started debugging with `bundle open aasm` and pry and I found that the `ClassInvoker` has a `instance` method that memoizes the instance returned from the `retrieve_instance` method, but the `instance` method was only being used by `log_source_location` and `log_method_info` methods while `invoke_subject` was calling `retrieve_instance` directly resulting in `retrieve_instance` being called twice. * Update `invoke_subject` method to use `instance.call` so that the instance will be memoized and subsequent calls to `instance` won't try to instantiate the class a second time.
This commit is contained in:
parent
7d49b11a86
commit
5d22f691fe
2 changed files with 13 additions and 1 deletions
|
@ -17,7 +17,7 @@ module AASM
|
||||||
end
|
end
|
||||||
|
|
||||||
def invoke_subject
|
def invoke_subject
|
||||||
@result = retrieve_instance.call
|
@result = instance.call
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -52,6 +52,18 @@ describe AASM::Core::Invokers::ClassInvoker do
|
||||||
|
|
||||||
expect(subject.failures.first).to be_a(Method)
|
expect(subject.failures.first).to be_a(Method)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when a failure occurs' do
|
||||||
|
let(:target) { Class.new { def initialize(_r, *_a); end; def call; end } }
|
||||||
|
|
||||||
|
it 'only instantiates subject class one time' do
|
||||||
|
target_instance = target.new(record, *args)
|
||||||
|
|
||||||
|
expect(target).to receive(:new).with(record, *args).and_return(target_instance).once
|
||||||
|
|
||||||
|
expect { subject.invoke }.not_to raise_error
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue