Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve disable and disable_tracking, add their inverses #240

Merged
merged 4 commits into from
Apr 14, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* [#236](https://github.com/mongoid/mongoid-history/pull/236): Fix Ruby 2.7 keyword argument warnings - [@vasilysn](https://github.com/vasilysn).
* [#237](https://github.com/mongoid/mongoid-history/pull/237): Fix tracking subclasses with additional fields - [@getaroom](https://github.com/getaroom).
* [#239](https://github.com/mongoid/mongoid-history/pull/239): Optimize `modified_attributes_for_create` 6-7x - [@getaroom](https://github.com/getaroom).
* [#240](https://github.com/mongoid/mongoid-history/pull/240): `Mongoid::History.disable` and `disable_tracking` now restore the original state if given a block and can be run without a block plus `Mongoid::History.enable` and `enable_tracking` have been added - [@getaroom](https://github.com/getaroom).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split in two lines with the same PR. There are two changes here.


### 0.8.2 (2019/12/02)

Expand Down
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,34 @@ Comment.disable_tracking do
comment.update_attributes(:title => "Test 3")
end

# globally disable all history tracking
# disable tracking for comments by default
Comment.disable_tracking
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's alias disable_tracking to disable_tracking! and document the latter as the recommended way to do this. So either

Comment.disable_tracking!

or

Comment.disable_tracking do
 ...
end


# enable tracking for comments within a block
Comment.enable_tracking do
comment.update_attributes(:title => "Test 3")
end

# renable tracking for comments by default
Comment.enable_tracking

# globally disable all history tracking within a block
Mongoid::History.disable do
comment.update_attributes(:title => "Test 3")
user.update_attributes(:name => "Eddie Van Halen")
end

# globally disable all history tracking by default
Mongoid::History.disable
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the above, disable! and enable!


# globally enable all history tracking within a block
Mongoid::History.enable do
comment.update_attributes(:title => "Test 3")
user.update_attributes(:name => "Eddie Van Halen")
end

# globally renable all history tracking by default
Mongoid::History.enable
```

You may want to track changes on all fields.
Expand Down
13 changes: 11 additions & 2 deletions lib/mongoid/history.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,20 @@ class << self
attr_accessor :modifier_class_name
attr_accessor :current_user_method

def disable(&_block)
def disable
original_flag = store[GLOBAL_TRACK_HISTORY_FLAG]
store[GLOBAL_TRACK_HISTORY_FLAG] = false
yield
yield if block_given?
ensure
store[GLOBAL_TRACK_HISTORY_FLAG] = original_flag if block_given?
end

def enable
original_flag = store[GLOBAL_TRACK_HISTORY_FLAG]
store[GLOBAL_TRACK_HISTORY_FLAG] = true
yield if block_given?
ensure
store[GLOBAL_TRACK_HISTORY_FLAG] = original_flag if block_given?
end

def enabled?
Expand Down
13 changes: 11 additions & 2 deletions lib/mongoid/history/trackable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,20 @@ def dynamic_enabled?
Mongoid::Compatibility::Version.mongoid3? || (self < Mongoid::Attributes::Dynamic).present?
end

def disable_tracking(&_block)
def disable_tracking
original_flag = Mongoid::History.store[track_history_flag]
Mongoid::History.store[track_history_flag] = false
yield
yield if block_given?
ensure
Mongoid::History.store[track_history_flag] = original_flag if block_given?
end

def enable_tracking
original_flag = Mongoid::History.store[track_history_flag]
Mongoid::History.store[track_history_flag] = true
yield if block_given?
ensure
Mongoid::History.store[track_history_flag] = original_flag if block_given?
end

def track_history_flag
Expand Down
135 changes: 131 additions & 4 deletions spec/unit/trackable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,11 @@ class MySubModel < MyModel

describe '#track_history?' do
shared_examples_for 'history tracking' do
after do
Mongoid::History.store[Mongoid::History::GLOBAL_TRACK_HISTORY_FLAG] = true
Mongoid::History.store[MyModel.track_history_flag] = true
end

context 'when tracking is globally enabled' do
it 'should be enabled on the current thread' do
expect(Mongoid::History.enabled?).to eq(true)
Expand All @@ -283,7 +288,40 @@ class MySubModel < MyModel
end
end

it 'should be rescued if an exception occurs' do
it 'should be enabled within enable_tracking' do
MyModel.disable_tracking do
MyModel.enable_tracking do
expect(Mongoid::History.enabled?).to eq(true)
expect(MyModel.new.track_history?).to eq(true)
end
end
end

it 'should still be disabled after completing a nested disable_tracking' do
MyModel.disable_tracking do
MyModel.disable_tracking {}
expect(Mongoid::History.enabled?).to eq(true)
expect(MyModel.new.track_history?).to eq(false)
end
end

it 'should still be enabled after completing a nested enable_tracking' do
MyModel.enable_tracking do
MyModel.enable_tracking {}
expect(Mongoid::History.enabled?).to eq(true)
expect(MyModel.new.track_history?).to eq(true)
end
end

it 'should restore the original state after completing enable_tracking' do
MyModel.disable_tracking do
MyModel.enable_tracking {}
expect(Mongoid::History.enabled?).to eq(true)
expect(MyModel.new.track_history?).to eq(false)
end
end

it 'should be rescued if an exception occurs in disable_tracking' do
begin
MyModel.disable_tracking do
raise 'exception'
Expand All @@ -294,6 +332,33 @@ class MySubModel < MyModel
expect(MyModel.new.track_history?).to eq(true)
end

it 'should be rescued if an exception occurs in enable_tracking' do
MyModel.disable_tracking do
begin
MyModel.enable_tracking do
raise 'exception'
end
rescue
end
expect(Mongoid::History.enabled?).to eq(true)
expect(MyModel.new.track_history?).to eq(false)
end
end

it 'should stay disabled if disable_tracking called without a block' do
MyModel.disable_tracking
expect(Mongoid::History.enabled?).to eq(true)
expect(MyModel.new.track_history?).to eq(false)
end

it 'should stay enabled if enable_tracking called without a block' do
MyModel.disable_tracking do
MyModel.enable_tracking
expect(Mongoid::History.enabled?).to eq(true)
expect(MyModel.new.track_history?).to eq(true)
end
end

context 'with multiple classes' do
before :each do
class MyModel2
Expand All @@ -317,14 +382,49 @@ class MyModel2
end
end

context 'when tracking is globally disabled' do
context 'when changing global tracking' do
it 'should be disabled by the global disablement' do
Mongoid::History.disable do
expect(Mongoid::History.enabled?).to eq(false)
expect(MyModel.new.track_history?).to eq(false)
end
end

it 'should be enabled by the global enablement' do
Mongoid::History.disable do
Mongoid::History.enable do
expect(Mongoid::History.enabled?).to eq(true)
expect(MyModel.new.track_history?).to eq(true)
end
end
end

it 'should restore the original state after completing enable' do
Mongoid::History.disable do
Mongoid::History.enable {}
expect(Mongoid::History.enabled?).to eq(false)
expect(MyModel.new.track_history?).to eq(false)
end
end

it 'should still be disabled after completing a nested disable' do
Mongoid::History.disable do
Mongoid::History.disable {}
expect(Mongoid::History.enabled?).to eq(false)
expect(MyModel.new.track_history?).to eq(false)
end
end

it 'should still be enabled after completing a nested enable' do
Mongoid::History.disable do
Mongoid::History.enable do
Mongoid::History.enable {}
expect(Mongoid::History.enabled?).to eq(true)
expect(MyModel.new.track_history?).to eq(true)
end
end
end

it 'should be disabled within disable_tracking' do
Mongoid::History.disable do
MyModel.disable_tracking do
Expand All @@ -334,7 +434,7 @@ class MyModel2
end
end

it 'should be rescued if an exception occurs' do
it 'should be rescued if an exception occurs in disable' do
Mongoid::History.disable do
begin
MyModel.disable_tracking do
Expand All @@ -347,6 +447,33 @@ class MyModel2
end
end

it 'should be rescued if an exception occurs in enable' do
Mongoid::History.disable do
begin
Mongoid::History.enable do
raise 'exception'
end
rescue
end
expect(Mongoid::History.enabled?).to eq(false)
expect(MyModel.new.track_history?).to eq(false)
end
end

it 'should stay disabled if disable called without a block' do
Mongoid::History.disable
expect(Mongoid::History.enabled?).to eq(false)
expect(MyModel.new.track_history?).to eq(false)
end

it 'should stay enabled if enable called without a block' do
Mongoid::History.disable do
Mongoid::History.enable
expect(Mongoid::History.enabled?).to eq(true)
expect(MyModel.new.track_history?).to eq(true)
end
end

context 'with multiple classes' do
before :each do
class MyModel2
Expand All @@ -361,7 +488,7 @@ class MyModel2
Object.send(:remove_const, :MyModel2)
end

it 'should be disabled only for the class that calls disable_tracking' do
it 'should be disabled for all classes' do
Mongoid::History.disable do
MyModel.disable_tracking do
expect(Mongoid::History.enabled?).to eq(false)
Expand Down