From eb2641f6a04bf5399362f5bc646f85f8ec7ade1f Mon Sep 17 00:00:00 2001 From: ujihisa Date: Wed, 25 Nov 2020 12:58:37 -0800 Subject: [PATCH 1/2] Update dirty before callbacks * ActiveRecord updates its changes/previous_changes before after_create/after_update callbacks * However, MongoMapper does that after the callbacks, therefore the changes/previous_changes values don't match with equivalent code in ActiveRecord. --- lib/mongo_mapper/plugins/dirty.rb | 2 +- spec/functional/dirty_with_callbacks_spec.rb | 22 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 spec/functional/dirty_with_callbacks_spec.rb diff --git a/lib/mongo_mapper/plugins/dirty.rb b/lib/mongo_mapper/plugins/dirty.rb index cc5e3c943..72d66305a 100644 --- a/lib/mongo_mapper/plugins/dirty.rb +++ b/lib/mongo_mapper/plugins/dirty.rb @@ -13,7 +13,7 @@ def create_accessors_for(key) end end - def create_or_update(*) + def save_to_collection(*) super.tap do changes_applied end diff --git a/spec/functional/dirty_with_callbacks_spec.rb b/spec/functional/dirty_with_callbacks_spec.rb new file mode 100644 index 000000000..94de8ea56 --- /dev/null +++ b/spec/functional/dirty_with_callbacks_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe 'DirtyWithCallbacks' do + it 'should update its changes/previous_changes before after_create/after_update callbacks' do + document = Doc { + key :x, String + + after_create { + changes.should == {} + previous_changes.should == {'x' => [nil, 'hello']} + } + after_update { + changes.should == {} + previous_changes.should == {'x' => ['hello', 'world']} + } + } + + d = document.create(x: 'hello') + d.x = 'world' + d.save! + end +end From ad9e8196d125d243ffe1351ed135b869417ba3df Mon Sep 17 00:00:00 2001 From: ujihisa Date: Wed, 25 Nov 2020 19:41:00 -0800 Subject: [PATCH 2/2] Test after_save * Also cover the case when some callbacks didn't get called --- spec/functional/dirty_with_callbacks_spec.rb | 47 +++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/spec/functional/dirty_with_callbacks_spec.rb b/spec/functional/dirty_with_callbacks_spec.rb index 94de8ea56..db299070e 100644 --- a/spec/functional/dirty_with_callbacks_spec.rb +++ b/spec/functional/dirty_with_callbacks_spec.rb @@ -2,21 +2,58 @@ describe 'DirtyWithCallbacks' do it 'should update its changes/previous_changes before after_create/after_update callbacks' do + history = {} + document = Doc { key :x, String + after_save { + history[:after_save] = { + changes: changes, + previous_changes: previous_changes, + } + } after_create { - changes.should == {} - previous_changes.should == {'x' => [nil, 'hello']} + history[:after_create] = { + changes: changes, + previous_changes: previous_changes, + } } after_update { - changes.should == {} - previous_changes.should == {'x' => ['hello', 'world']} + history[:after_update] = { + changes: changes, + previous_changes: previous_changes, + } } } - d = document.create(x: 'hello') + d = document.new(x: 'hello') + d.save + + history.should == { + after_save: { + changes: {}, + previous_changes: {'x' => [nil, 'hello']}, + }, + after_create: { + changes: {}, + previous_changes: {'x' => [nil, 'hello']}, + }, + } + history.clear + d.x = 'world' d.save! + + history.should == { + after_save: { + changes: {}, + previous_changes: {'x' => ['hello', 'world']}, + }, + after_update: { + changes: {}, + previous_changes: {'x' => ['hello', 'world']}, + }, + } end end