From 41dfbeeee33ddc74e0c27de7f37a7be82059613e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20Cl=C3=A9ment?= Date: Wed, 22 Sep 2021 16:59:08 +0200 Subject: [PATCH 1/3] Create test for namespace timestamps --- .../timestamps_with_namespace_machine_example.rb | 13 +++++++++++++ spec/unit/timestamps_spec.rb | 5 +++++ 2 files changed, 18 insertions(+) create mode 100644 spec/models/timestamps_with_namespace_machine_example.rb diff --git a/spec/models/timestamps_with_namespace_machine_example.rb b/spec/models/timestamps_with_namespace_machine_example.rb new file mode 100644 index 00000000..5c3fae75 --- /dev/null +++ b/spec/models/timestamps_with_namespace_machine_example.rb @@ -0,0 +1,13 @@ +class TimestampsWithNamespaceMachineExample + include AASM + + attr_accessor :new_opened_at + + aasm :my_state, timestamps: true, namespace: :new do + state :opened + + event :open do + transitions to: :opened + end + end +end diff --git a/spec/unit/timestamps_spec.rb b/spec/unit/timestamps_spec.rb index 0c36ec48..65e2f87b 100644 --- a/spec/unit/timestamps_spec.rb +++ b/spec/unit/timestamps_spec.rb @@ -29,4 +29,9 @@ object = TimestampsWithNamedMachineExample.new expect { object.open }.to change { object.opened_at }.from(nil).to(instance_of(::Time)) end + + it 'calls a timestamp setter based on the state name and namespace when entering a new state using a namespace state machine' do + object = TimestampsWithNamespaceMachineExample.new + expect { object.open }.to change { object.new_opened_at }.from(nil).to(instance_of(::Time)) + end end From 4a450b0c504342f4210a3290aed0314d55a59654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20Cl=C3=A9ment?= Date: Wed, 22 Sep 2021 17:04:17 +0200 Subject: [PATCH 2/3] Create timestamps by prepending the namespace to the state when present --- lib/aasm/base.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/aasm/base.rb b/lib/aasm/base.rb index 5e870cfc..8c5c11d7 100644 --- a/lib/aasm/base.rb +++ b/lib/aasm/base.rb @@ -55,7 +55,7 @@ def initialize(klass, name, state_machine, options={}, &block) configure :logger, Logger.new(STDERR) # setup timestamp-setting callback if enabled - setup_timestamps(@name) + setup_timestamps(@name, namespace) # make sure to raise an error if no_direct_assignment is enabled # and attribute is directly assigned though @@ -263,12 +263,13 @@ def skip_instance_level_validation(event, name, aasm_name, klass) end end - def setup_timestamps(aasm_name) + def setup_timestamps(aasm_name, namespace) return unless @state_machine.config.timestamps after_all_transitions do if self.class.aasm(:"#{aasm_name}").state_machine.config.timestamps - ts_setter = "#{aasm(aasm_name).to_state}_at=" + base_setter = "#{aasm(aasm_name).to_state}_at=" + ts_setter = !!namespace ? "#{namespace}_#{base_setter}" : base_setter respond_to?(ts_setter) && send(ts_setter, ::Time.now) end end From 61fe78edce71d3b160cdb7d824c99a9bf6bb40b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20Cl=C3=A9ment?= Date: Thu, 23 Sep 2021 09:43:21 +0200 Subject: [PATCH 3/3] Refactor change --- lib/aasm/base.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/aasm/base.rb b/lib/aasm/base.rb index 8c5c11d7..8950553a 100644 --- a/lib/aasm/base.rb +++ b/lib/aasm/base.rb @@ -55,7 +55,7 @@ def initialize(klass, name, state_machine, options={}, &block) configure :logger, Logger.new(STDERR) # setup timestamp-setting callback if enabled - setup_timestamps(@name, namespace) + setup_timestamps(@name) # make sure to raise an error if no_direct_assignment is enabled # and attribute is directly assigned though @@ -263,11 +263,12 @@ def skip_instance_level_validation(event, name, aasm_name, klass) end end - def setup_timestamps(aasm_name, namespace) + def setup_timestamps(aasm_name) return unless @state_machine.config.timestamps after_all_transitions do if self.class.aasm(:"#{aasm_name}").state_machine.config.timestamps + namespace = self.class.aasm(:"#{aasm_name}").state_machine.config.namespace base_setter = "#{aasm(aasm_name).to_state}_at=" ts_setter = !!namespace ? "#{namespace}_#{base_setter}" : base_setter respond_to?(ts_setter) && send(ts_setter, ::Time.now)