1
0
Fork 0
mirror of https://github.com/paper-trail-gem/paper_trail.git synced 2022-11-09 11:33:19 -05:00
paper-trail-gem--paper_trail/test/functional/thread_safety_test.rb
Jared Beck ad3806fcbb An idea to combat model pollution
Problem
-------

`has_paper_trail` adds too many methods to the ActiveRecord model.

> If I'm counting correctly, installing the paper_trail gem adds 36 instance
> methods and 10 class methods to all of your active record models. Of those
> 46, 13 have a prefix, either "pt_" or "paper_trail_". I don't know what the
> best way to deal with this is. Ideally, we'd add far fewer methods to
> people's models. If we were able to add fewer methods to models, then I
> wouldn't mind prefixing all of them.
> https://github.com/airblade/paper_trail/issues/703

Solution
--------

Add only two methods to the AR model.

1. An instance method `#paper_trail`
2. A class method `.paper_trail`

The instance method would return a `RecordTrail` and the class method would
return a `ClassTrail`. Those names are totally up for debate.

Advantages
----------

- Plain ruby, easy to understand
- Adding new methods to e.g. the `RecordTrail` does not add any methods to
  the AR model.
- Methods privacy is more strongly enforced.
- Enables isolated testing of e.g. `RecordTrail`; it can be constructed with a
  mock AR instance.

Disadvantages
-------------

- Two new classes, though they are simple.
2016-06-06 01:18:31 -04:00

46 lines
1.1 KiB
Ruby

require "test_helper"
class ThreadSafetyTest < ActionController::TestCase
test "thread-safe when using #set_paper_trail_whodunnit" do
blocked = true
slow_thread = Thread.new do
controller = TestController.new
controller.send :set_paper_trail_whodunnit
sleep 0.001 while blocked
PaperTrail.whodunnit
end
fast_thread = Thread.new do
controller = TestController.new
controller.send :set_paper_trail_whodunnit
who = PaperTrail.whodunnit
blocked = false
who
end
assert_not_equal slow_thread.value, fast_thread.value
end
test "thread-safe when using #without_versioning" do
enabled = nil
slow_thread = Thread.new do
Widget.new.paper_trail.without_versioning do
sleep(0.01)
enabled = Widget.paper_trail.enabled?
sleep(0.01)
end
enabled
end
fast_thread = Thread.new do
sleep(0.005)
Widget.paper_trail.enabled?
end
assert_not_equal slow_thread.value, fast_thread.value
assert Widget.paper_trail.enabled?
assert PaperTrail.enabled_for_model?(Widget)
end
end