diff --git a/lib/activerecord-bitemporal/bitemporal.rb b/lib/activerecord-bitemporal/bitemporal.rb index 01c31b6..5e43fc2 100644 --- a/lib/activerecord-bitemporal/bitemporal.rb +++ b/lib/activerecord-bitemporal/bitemporal.rb @@ -346,17 +346,20 @@ def destroy(force_delete: false, operated_at: Time.current) _run_destroy_callbacks { @destroyed = update_transaction_to(operated_at) - # 削除時の状態を履歴レコードとして保存する - duplicated_instance.valid_to = target_datetime - duplicated_instance.transaction_from = operated_at - duplicated_instance.save_without_bitemporal_callbacks!(validate: false) - if @destroyed - @_swapped_id_previously_was = swapped_id - @_swapped_id = duplicated_instance.swapped_id - self.valid_from = duplicated_instance.valid_from - self.valid_to = duplicated_instance.valid_to - self.transaction_from = duplicated_instance.transaction_from - self.transaction_to = duplicated_instance.transaction_to + # force_update の場合は削除時の状態の履歴を残さない + unless force_update? + # 削除時の状態を履歴レコードとして保存する + duplicated_instance.valid_to = target_datetime + duplicated_instance.transaction_from = operated_at + duplicated_instance.save_without_bitemporal_callbacks!(validate: false) + if @destroyed + @_swapped_id_previously_was = swapped_id + @_swapped_id = duplicated_instance.swapped_id + self.valid_from = duplicated_instance.valid_from + self.valid_to = duplicated_instance.valid_to + self.transaction_from = duplicated_instance.transaction_from + self.transaction_to = duplicated_instance.transaction_to + end end } raise ActiveRecord::RecordInvalid unless @destroyed diff --git a/spec/activerecord-bitemporal/bitemporal_spec.rb b/spec/activerecord-bitemporal/bitemporal_spec.rb index 7c58f02..7490b30 100644 --- a/spec/activerecord-bitemporal/bitemporal_spec.rb +++ b/spec/activerecord-bitemporal/bitemporal_spec.rb @@ -1204,6 +1204,21 @@ class EmployeeWithUniquness < Employee it { expect { subject }.to change(employee, :transaction_from).from(updated_time).to(destroyed_time) } it { expect { subject }.not_to change(employee, :transaction_to) } end + + context "with `#force_update`" do + subject { Timecop.freeze(destroyed_time) { employee.force_update { employee.destroy } } } + + it { expect { subject }.to change(Employee, :count).by(-1) } + it { expect { subject }.to change(employee, :destroyed?).from(false).to(true) } + it { expect { subject }.not_to change(employee, :valid_from) } + it { expect { subject }.not_to change(employee, :valid_to) } + it { expect { subject }.not_to change(employee, :transaction_from) } + it { expect { subject }.to change(employee, :transaction_to).from(ActiveRecord::Bitemporal::DEFAULT_TRANSACTION_TO).to(destroyed_time) } + it { expect { subject }.not_to change { Employee.ignore_valid_datetime.within_deleted.count } } + it { expect { subject }.not_to change(employee, :swapped_id) } + it { expect { subject }.not_to change(employee, :swapped_id_previously_was) } + it { expect(subject).to eq employee } + end end describe "#touch" do