diff --git a/CHANGELOG.md b/CHANGELOG.md index 339473d7..5eec2f8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ recommendations of [keepachangelog.com](http://keepachangelog.com/). ### Added -- None +- [#932](https://github.com/airblade/paper_trail/pull/932) - + `PaperTrail.whodunnit` now accepts a block. ### Fixed diff --git a/README.md b/README.md index f40b3d90..5bbe0494 100644 --- a/README.md +++ b/README.md @@ -708,6 +708,14 @@ widget.update_attributes :name => 'Wibble' widget.versions.last.whodunnit # Andy Stewart ``` +`whodunnit` also accepts a block, a convenient way to temporarily set the value. + +```ruby +PaperTrail.whodunnit("Dorian MariƩ") do + widget.update_attributes :name => 'Wibble' +end +``` + If your controller has a `current_user` method, PaperTrail provides a `before_action` that will assign `current_user.id` to `PaperTrail.whodunnit`. You can add this `before_action` to your `ApplicationController`. diff --git a/lib/paper_trail.rb b/lib/paper_trail.rb index 4f6815d1..a44d13e2 100644 --- a/lib/paper_trail.rb +++ b/lib/paper_trail.rb @@ -87,10 +87,33 @@ module PaperTrail paper_trail_store[:whodunnit] = value end - # Returns who is reponsible for any changes that occur. + # If nothing passed, returns who is reponsible for any changes that occur. + # + # PaperTrail.whodunnit = "someone" + # PaperTrail.whodunnit # => "someone" + # + # If value and block passed, set this value as whodunnit for the duration of the block + # + # PaperTrail.whodunnit("me") do + # puts PaperTrail.whodunnit # => "me" + # end + # # @api public - def whodunnit - paper_trail_store[:whodunnit] + def whodunnit(value = nil) + if value + raise ArgumentError, "no block given" unless block_given? + + previous_whodunnit = paper_trail_store[:whodunnit] + paper_trail_store[:whodunnit] = value + + begin + yield + ensure + paper_trail_store[:whodunnit] = previous_whodunnit + end + else + paper_trail_store[:whodunnit] + end end # Sets any information from the controller that you want PaperTrail to diff --git a/spec/paper_trail_spec.rb b/spec/paper_trail_spec.rb index 20779a88..c2a1e381 100644 --- a/spec/paper_trail_spec.rb +++ b/spec/paper_trail_spec.rb @@ -75,10 +75,31 @@ RSpec.describe PaperTrail do end describe ".whodunnit" do - before(:all) { described_class.whodunnit = "foobar" } + context "when set globally" do + before(:all) { described_class.whodunnit = "foobar" } - it "is nil by default" do - expect(described_class.whodunnit).to be_nil + it "is set to `nil` by default" do + expect(described_class.whodunnit).to be_nil + end + end + + context "with block passed" do + it "sets whodunnit only for the block passed" do + described_class.whodunnit("foo") do + expect(described_class.whodunnit).to eq("foo") + end + + expect(described_class.whodunnit).to be_nil + end + + it "sets whodunnit only for the current thread" do + described_class.whodunnit("foo") do + expect(described_class.whodunnit).to eq("foo") + Thread.new { expect(described_class.whodunnit).to be_nil }.join + end + + expect(described_class.whodunnit).to be_nil + end end end