paper_trail 2.7.2 → 3.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.gitignore +1 -0
 - data/.rspec +3 -0
 - data/.travis.yml +13 -4
 - data/CHANGELOG.md +15 -0
 - data/README.md +109 -38
 - data/Rakefile +9 -3
 - data/gemfiles/3.0.gemfile +31 -0
 - data/lib/generators/paper_trail/install_generator.rb +7 -4
 - data/lib/paper_trail.rb +15 -9
 - data/lib/paper_trail/cleaner.rb +34 -0
 - data/lib/paper_trail/frameworks/cucumber.rb +31 -0
 - data/lib/paper_trail/frameworks/rails.rb +79 -0
 - data/lib/paper_trail/frameworks/rspec.rb +24 -0
 - data/lib/paper_trail/frameworks/rspec/extensions.rb +20 -0
 - data/lib/paper_trail/frameworks/sinatra.rb +31 -0
 - data/lib/paper_trail/has_paper_trail.rb +22 -20
 - data/lib/paper_trail/version.rb +188 -161
 - data/lib/paper_trail/version_number.rb +1 -1
 - data/paper_trail.gemspec +10 -6
 - data/spec/models/widget_spec.rb +13 -0
 - data/spec/paper_trail_spec.rb +47 -0
 - data/spec/spec_helper.rb +41 -0
 - data/test/dummy/app/controllers/widgets_controller.rb +10 -2
 - data/test/dummy/app/models/protected_widget.rb +1 -1
 - data/test/dummy/app/models/widget.rb +6 -1
 - data/test/dummy/app/versions/post_version.rb +1 -1
 - data/test/dummy/config/application.rb +5 -6
 - data/test/dummy/config/environments/development.rb +6 -4
 - data/test/dummy/config/environments/production.rb +6 -0
 - data/test/dummy/config/environments/test.rb +4 -4
 - data/test/dummy/config/initializers/paper_trail.rb +4 -2
 - data/test/functional/controller_test.rb +2 -2
 - data/test/functional/modular_sinatra_test.rb +44 -0
 - data/test/functional/sinatra_test.rb +45 -0
 - data/test/functional/thread_safety_test.rb +1 -1
 - data/test/paper_trail_test.rb +2 -2
 - data/test/unit/cleaner_test.rb +143 -0
 - data/test/unit/inheritance_column_test.rb +3 -3
 - data/test/unit/model_test.rb +74 -55
 - data/test/unit/protected_attrs_test.rb +12 -7
 - data/test/unit/timestamp_test.rb +2 -2
 - data/test/unit/version_test.rb +37 -20
 - metadata +86 -26
 - data/lib/paper_trail/controller.rb +0 -75
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: b667567a3273c0c6d95a75068b7d4e0b5d5c71ba
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 83853768990c1f61e1c9149bc275126254b87415
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: ba6c131b28bb5a060acdd08839cc53d58407961633389d53775ca0ff47d034964a5d192f56dc3e2315fd0bcd040439b06640120b316e65bfdd68acb9783e0099
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 1e546deade76f16dfd47a2414cf9d0d4021c45fa7d5bf2d825e62f79ba22cc04f0235102fd4c7708ea4f121e8ddedacbc07450ca74dc58c152161887368dc4e8
         
     | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/.rspec
    ADDED
    
    
    
        data/.travis.yml
    CHANGED
    
    | 
         @@ -2,11 +2,20 @@ language: ruby 
     | 
|
| 
       2 
2 
     | 
    
         
             
            rvm:
         
     | 
| 
       3 
3 
     | 
    
         
             
              - 2.0.0
         
     | 
| 
       4 
4 
     | 
    
         
             
              - 1.9.3
         
     | 
| 
       5 
     | 
    
         
            -
              - 1.9.2
         
     | 
| 
       6 
5 
     | 
    
         
             
              - 1.8.7
         
     | 
| 
       7 
     | 
    
         
            -
              - ree
         
     | 
| 
       8 
     | 
    
         
            -
              - jruby-18mode
         
     | 
| 
       9 
6 
     | 
    
         
             
              - jruby-19mode
         
     | 
| 
      
 7 
     | 
    
         
            +
              - jruby-18mode
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            before_install:
         
     | 
| 
      
 10 
     | 
    
         
            +
              - gem install bundler --version '~> 1.3'
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            gemfile:
         
     | 
| 
      
 13 
     | 
    
         
            +
              - Gemfile
         
     | 
| 
      
 14 
     | 
    
         
            +
              - gemfiles/3.0.gemfile
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
       10 
16 
     | 
    
         
             
            matrix:
         
     | 
| 
       11 
17 
     | 
    
         
             
              allow_failures:
         
     | 
| 
       12 
     | 
    
         
            -
                - rvm:  
     | 
| 
      
 18 
     | 
    
         
            +
                - rvm: jruby-18mode
         
     | 
| 
      
 19 
     | 
    
         
            +
                  gemfile: Gemfile
         
     | 
| 
      
 20 
     | 
    
         
            +
                - rvm: 1.8.7
         
     | 
| 
      
 21 
     | 
    
         
            +
                  gemfile: Gemfile
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,3 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ## 3.0.0 (Unreleased)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              - [#264](https://github.com/airblade/paper_trail/pull/264) - Allow unwrapped symbol to be passed in to the `on` option.
         
     | 
| 
      
 4 
     | 
    
         
            +
              - [#224](https://github.com/airblade/paper_trail/issues/224)/[#236](https://github.com/airblade/paper_trail/pull/236) -
         
     | 
| 
      
 5 
     | 
    
         
            +
                Fixed compatibility with [ActsAsTaggableOn](https://github.com/mbleigh/acts-as-taggable-on).
         
     | 
| 
      
 6 
     | 
    
         
            +
              - [#235](https://github.com/airblade/paper_trail/pull/235) - Dropped unnecessary secondary sort on `versions` association.
         
     | 
| 
      
 7 
     | 
    
         
            +
              - [#216](https://github.com/airblade/paper_trail/pull/216) - Added helper & extension for [RSpec](https://github.com/rspec/rspec),
         
     | 
| 
      
 8 
     | 
    
         
            +
                and helper for [Cucumber](http://cukes.info).
         
     | 
| 
      
 9 
     | 
    
         
            +
              - [#212](https://github.com/airblade/paper_trail/pull/212) - Added `PaperTrail::Cleaner` module, useful for discarding draft versions.
         
     | 
| 
      
 10 
     | 
    
         
            +
              - [#207](https://github.com/airblade/paper_trail/issues/207) - Versions for `'create'` events are now created with `create!` instead of 
         
     | 
| 
      
 11 
     | 
    
         
            +
                `create` so that an exception gets raised if it is appropriate to do so.
         
     | 
| 
      
 12 
     | 
    
         
            +
              - [#199](https://github.com/airblade/paper_trail/pull/199) - Rails 4 compatibility.
         
     | 
| 
      
 13 
     | 
    
         
            +
              - [#165](https://github.com/airblade/paper_trail/pull/165) - Namespaced the `Version` class under the `PaperTrail` module.
         
     | 
| 
      
 14 
     | 
    
         
            +
              - [#119](https://github.com/airblade/paper_trail/issues/119) - Support for [Sinatra](http://www.sinatrarb.com/); decoupled gem from `Rails`.
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
       1 
16 
     | 
    
         
             
            ## 2.7.2
         
     | 
| 
       2 
17 
     | 
    
         | 
| 
       3 
18 
     | 
    
         
             
              - [#228](https://github.com/airblade/paper_trail/issues/228) - Refactored default `user_for_paper_trail` method implementation
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,4 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # PaperTrail [](http://travis-ci.org/airblade/paper_trail) [](https://gemnasium.com/airblade/paper_trail)
         
     | 
| 
      
 1 
     | 
    
         
            +
            # PaperTrail [](http://travis-ci.org/airblade/paper_trail) [](https://gemnasium.com/airblade/paper_trail)
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            PaperTrail lets you track changes to your models' data.  It's good for auditing or versioning.  You can see how a model looked at any stage in its lifecycle, revert it to any version, and even undelete it after it's been destroyed.
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
         @@ -29,10 +29,49 @@ There's an excellent [Railscast on implementing Undo with Paper Trail](http://ra 
     | 
|
| 
       29 
29 
     | 
    
         
             
            * Threadsafe.
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
            ##  
     | 
| 
      
 32 
     | 
    
         
            +
            ## Compatibility
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
            Works  
     | 
| 
      
 34 
     | 
    
         
            +
            Works with ActiveRecord 4 and ActiveRecord 3. Note: this code is on the `master` branch and tagged `v3.x`.
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
      
 36 
     | 
    
         
            +
            **You are reading the docs for the `master` branch. The latest release of PaperTrail is 2.7.2, the docs for which can be viewed on the [`2.7-stable`](https://github.com/airblade/paper_trail/tree/2.7-stable branch).**
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            Version 2 is on the branch named [`2.7-stable`](https://github.com/airblade/paper_trail/tree/2.7-stable) and is tagged `v2.x`, and works with Rails 3.
         
     | 
| 
      
 39 
     | 
    
         
            +
            The Rails 2.3 code is on the [`rails2`](https://github.com/airblade/paper_trail/tree/rails2) branch and tagged `v1.x`. These branches are both stable with their respective versions of Rails but will not have new features added/backported to them.
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            ## Installation
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            ### Rails 3 & 4
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            1. Install PaperTrail as a gem via your `Gemfile`:
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                `gem 'paper_trail', '~> 3.0'`
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            2. Generate a migration which will add a `versions` table to your database.
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                `bundle exec rails generate paper_trail:install`
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            3. Run the migration.
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                `bundle exec rake db:migrate`
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            4. Add `has_paper_trail` to the models you want to track.
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            ### Sinatra
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            PaperTrail provides a helper extension that acts similar to the controller mixin it provides for `Rails` applications.
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            It will set `PaperTrail.whodunnit` to whatever is returned by a method named `user_for_paper_trail` which you can define inside your Sinatra Application. (by default it attempts to invoke a method named `current_user`)
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            If you're using the modular [Sinatra::Base](http://www.sinatrarb.com/intro.html#Modular%20vs.%20Classic%20Style) style of application, you will need to register the extension:
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 68 
     | 
    
         
            +
            # bleh_app.rb
         
     | 
| 
      
 69 
     | 
    
         
            +
            require 'sinatra/base'
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            class BlehApp < Sinatra::Base
         
     | 
| 
      
 72 
     | 
    
         
            +
              register Sinatra::PaperTrail
         
     | 
| 
      
 73 
     | 
    
         
            +
            end
         
     | 
| 
      
 74 
     | 
    
         
            +
            ```
         
     | 
| 
       36 
75 
     | 
    
         | 
| 
       37 
76 
     | 
    
         
             
            ## API Summary
         
     | 
| 
       38 
77 
     | 
    
         | 
| 
         @@ -72,7 +111,7 @@ Widget.paper_trail_off 
     | 
|
| 
       72 
111 
     | 
    
         
             
            Widget.paper_trail_on
         
     | 
| 
       73 
112 
     | 
    
         
             
            ```
         
     | 
| 
       74 
113 
     | 
    
         | 
| 
       75 
     | 
    
         
            -
            And a `Version` instance has these methods:
         
     | 
| 
      
 114 
     | 
    
         
            +
            And a `PaperTrail::Version` instance has these methods:
         
     | 
| 
       76 
115 
     | 
    
         | 
| 
       77 
116 
     | 
    
         
             
            ```ruby
         
     | 
| 
       78 
117 
     | 
    
         
             
            # Returns the item restored from this version.
         
     | 
| 
         @@ -124,7 +163,7 @@ This gives you a `versions` method which returns the paper trail of changes to y 
     | 
|
| 
       124 
163 
     | 
    
         | 
| 
       125 
164 
     | 
    
         
             
            ```ruby
         
     | 
| 
       126 
165 
     | 
    
         
             
            >> widget = Widget.find 42
         
     | 
| 
       127 
     | 
    
         
            -
            >> widget.versions             # [<Version>, <Version>, ...]
         
     | 
| 
      
 166 
     | 
    
         
            +
            >> widget.versions             # [<PaperTrail::Version>, <PaperTrail::Version>, ...]
         
     | 
| 
       128 
167 
     | 
    
         
             
            ```
         
     | 
| 
       129 
168 
     | 
    
         | 
| 
       130 
169 
     | 
    
         
             
            Once you have a version, you can find out what happened:
         
     | 
| 
         @@ -150,7 +189,7 @@ PaperTrail stores the pre-change version of the model, unlike some other auditin 
     | 
|
| 
       150 
189 
     | 
    
         | 
| 
       151 
190 
     | 
    
         
             
            >> widget.versions                             # []
         
     | 
| 
       152 
191 
     | 
    
         
             
            >> widget.update_attributes :name => 'Wotsit'
         
     | 
| 
       153 
     | 
    
         
            -
            >> widget.last.reify.name 
     | 
| 
      
 192 
     | 
    
         
            +
            >> widget.versions.last.reify.name             # 'Doobly'
         
     | 
| 
       154 
193 
     | 
    
         
             
            >> widget.versions.last.event                  # 'update'
         
     | 
| 
       155 
194 
     | 
    
         
             
            ```
         
     | 
| 
       156 
195 
     | 
    
         | 
| 
         @@ -193,7 +232,7 @@ class Article < ActiveRecord::Base 
     | 
|
| 
       193 
232 
     | 
    
         
             
            end
         
     | 
| 
       194 
233 
     | 
    
         
             
            ```
         
     | 
| 
       195 
234 
     | 
    
         | 
| 
       196 
     | 
    
         
            -
            You may also have the `Version` model save a custom string in it's `event` field instead of the typical `create`, `update`, `destroy`.
         
     | 
| 
      
 235 
     | 
    
         
            +
            You may also have the `PaperTrail::Version` model save a custom string in it's `event` field instead of the typical `create`, `update`, `destroy`.
         
     | 
| 
       197 
236 
     | 
    
         
             
            PaperTrail supplies a custom accessor method called `paper_trail_event`, which it will attempt to use to fill the `event` field before
         
     | 
| 
       198 
237 
     | 
    
         
             
            falling back on one of the default events.
         
     | 
| 
       199 
238 
     | 
    
         | 
| 
         @@ -233,7 +272,7 @@ class Article < ActiveRecord::Base 
     | 
|
| 
       233 
272 
     | 
    
         
             
            end
         
     | 
| 
       234 
273 
     | 
    
         
             
            ```
         
     | 
| 
       235 
274 
     | 
    
         | 
| 
       236 
     | 
    
         
            -
            This means that changes to just the `title` or `rating` will not store another version of the article.  It does not mean that the `title` and `rating` attributes will be ignored if some other change causes a new `Version` to be created.  For example:
         
     | 
| 
      
 275 
     | 
    
         
            +
            This means that changes to just the `title` or `rating` will not store another version of the article.  It does not mean that the `title` and `rating` attributes will be ignored if some other change causes a new `PaperTrail::Version` to be created.  For example:
         
     | 
| 
       237 
276 
     | 
    
         | 
| 
       238 
277 
     | 
    
         
             
            ```ruby
         
     | 
| 
       239 
278 
     | 
    
         
             
            >> a = Article.create
         
     | 
| 
         @@ -267,7 +306,7 @@ This means that only changes to the `title` will save a version of the article: 
     | 
|
| 
       267 
306 
     | 
    
         | 
| 
       268 
307 
     | 
    
         
             
            Passing both `:ignore` and `:only` options will result in the article being saved if a changed attribute is included in `:only` but not in `:ignore`.
         
     | 
| 
       269 
308 
     | 
    
         | 
| 
       270 
     | 
    
         
            -
            You can skip fields altogether with the `:skip` option.  As with `:ignore`, updates to these fields will not create a new `Version`.  In addition, these fields will not be included in the  
     | 
| 
      
 309 
     | 
    
         
            +
            You can skip fields altogether with the `:skip` option.  As with `:ignore`, updates to these fields will not create a new `PaperTrail::Version`.  In addition, these fields will not be included in the serialized version of the object whenever a new `PaperTrail::Version` is created.
         
     | 
| 
       271 
310 
     | 
    
         | 
| 
       272 
311 
     | 
    
         
             
            For example:
         
     | 
| 
       273 
312 
     | 
    
         | 
| 
         @@ -304,7 +343,7 @@ Undeleting is just as simple: 
     | 
|
| 
       304 
343 
     | 
    
         
             
            >> widget = Widget.find 42
         
     | 
| 
       305 
344 
     | 
    
         
             
            >> widget.destroy
         
     | 
| 
       306 
345 
     | 
    
         
             
            # Time passes....
         
     | 
| 
       307 
     | 
    
         
            -
            >> widget = Version.find(153).reify    # the widget as it was before it was destroyed
         
     | 
| 
      
 346 
     | 
    
         
            +
            >> widget = PaperTrail::Version.find(153).reify    # the widget as it was before it was destroyed
         
     | 
| 
       308 
347 
     | 
    
         
             
            >> widget.save                         # the widget lives!
         
     | 
| 
       309 
348 
     | 
    
         
             
            ```
         
     | 
| 
       310 
349 
     | 
    
         | 
| 
         @@ -363,7 +402,7 @@ You can find out whether a model instance is the current, live one -- or whether 
     | 
|
| 
       363 
402 
     | 
    
         
             
            If your `ApplicationController` has a `current_user` method, PaperTrail will store the value it returns in the `version`'s `whodunnit` column.  Note that this column is a string so you will have to convert it to an integer if it's an id and you want to look up the user later on:
         
     | 
| 
       364 
403 
     | 
    
         | 
| 
       365 
404 
     | 
    
         
             
            ```ruby
         
     | 
| 
       366 
     | 
    
         
            -
            >> last_change =  
     | 
| 
      
 405 
     | 
    
         
            +
            >> last_change = widget.versions.last
         
     | 
| 
       367 
406 
     | 
    
         
             
            >> user_who_made_the_change = User.find last_change.whodunnit.to_i
         
     | 
| 
       368 
407 
     | 
    
         
             
            ```
         
     | 
| 
       369 
408 
     | 
    
         | 
| 
         @@ -388,7 +427,7 @@ In a migration or in `rails console` you can set who is responsible like this: 
     | 
|
| 
       388 
427 
     | 
    
         
             
            You can avoid having to do this manually by setting your initializer to pick up the username of the current user from the OS, like this:
         
     | 
| 
       389 
428 
     | 
    
         | 
| 
       390 
429 
     | 
    
         
             
            ```ruby
         
     | 
| 
       391 
     | 
    
         
            -
            class Version < ActiveRecord::Base
         
     | 
| 
      
 430 
     | 
    
         
            +
            class PaperTrail::Version < ActiveRecord::Base
         
     | 
| 
       392 
431 
     | 
    
         
             
              if defined?(Rails::Console)
         
     | 
| 
       393 
432 
     | 
    
         
             
                PaperTrail.whodunnit = "#{`whoami`.strip}: console"
         
     | 
| 
       394 
433 
     | 
    
         
             
              elsif File.basename($0) == "rake"
         
     | 
| 
         @@ -423,7 +462,7 @@ To find out who made a `version`'s object look that way, use `version.originator 
     | 
|
| 
       423 
462 
     | 
    
         
             
            You can specify custom version subclasses with the `:class_name` option:
         
     | 
| 
       424 
463 
     | 
    
         | 
| 
       425 
464 
     | 
    
         
             
            ```ruby
         
     | 
| 
       426 
     | 
    
         
            -
            class PostVersion < Version
         
     | 
| 
      
 465 
     | 
    
         
            +
            class PostVersion < PaperTrail::Version
         
     | 
| 
       427 
466 
     | 
    
         
             
              # custom behaviour, e.g:
         
     | 
| 
       428 
467 
     | 
    
         
             
              self.table_name = :post_versions
         
     | 
| 
       429 
468 
     | 
    
         
             
            end
         
     | 
| 
         @@ -438,7 +477,7 @@ This allows you to store each model's versions in a separate table, which is use 
     | 
|
| 
       438 
477 
     | 
    
         
             
            If you are using Postgres, you should also define the sequence that your custom version class will use:
         
     | 
| 
       439 
478 
     | 
    
         | 
| 
       440 
479 
     | 
    
         
             
            ```ruby
         
     | 
| 
       441 
     | 
    
         
            -
            class PostVersion < Version
         
     | 
| 
      
 480 
     | 
    
         
            +
            class PostVersion < PaperTrail::Version
         
     | 
| 
       442 
481 
     | 
    
         
             
              self.table_name = :post_versions
         
     | 
| 
       443 
482 
     | 
    
         
             
              self.sequence_name = :post_version_id_seq
         
     | 
| 
       444 
483 
     | 
    
         
             
            end
         
     | 
| 
         @@ -451,7 +490,7 @@ If you only use custom version classes and don't use PaperTrail's built-in one, 
     | 
|
| 
       451 
490 
     | 
    
         
             
            - either declare PaperTrail's version class abstract like this (in `config/initializers/paper_trail_patch.rb`):
         
     | 
| 
       452 
491 
     | 
    
         | 
| 
       453 
492 
     | 
    
         
             
            ```ruby
         
     | 
| 
       454 
     | 
    
         
            -
            Version.module_eval do
         
     | 
| 
      
 493 
     | 
    
         
            +
            PaperTrail::Version.module_eval do
         
     | 
| 
       455 
494 
     | 
    
         
             
              self.abstract_class = true
         
     | 
| 
       456 
495 
     | 
    
         
             
            end
         
     | 
| 
       457 
496 
     | 
    
         
             
            ```
         
     | 
| 
         @@ -609,15 +648,17 @@ For example: 
     | 
|
| 
       609 
648 
     | 
    
         | 
| 
       610 
649 
     | 
    
         
             
            ```ruby
         
     | 
| 
       611 
650 
     | 
    
         
             
            # config/initializers/paper_trail.rb
         
     | 
| 
       612 
     | 
    
         
            -
             
     | 
| 
       613 
     | 
    
         
            -
               
     | 
| 
      
 651 
     | 
    
         
            +
            module PaperTrail
         
     | 
| 
      
 652 
     | 
    
         
            +
              class Version < ActiveRecord::Base
         
     | 
| 
      
 653 
     | 
    
         
            +
                attr_accessible :author_id, :word_count, :answer
         
     | 
| 
      
 654 
     | 
    
         
            +
              end
         
     | 
| 
       614 
655 
     | 
    
         
             
            end
         
     | 
| 
       615 
656 
     | 
    
         
             
            ```
         
     | 
| 
       616 
657 
     | 
    
         | 
| 
       617 
658 
     | 
    
         
             
            Why would you do this?  In this example, `author_id` is an attribute of `Article` and PaperTrail will store it anyway in serialized (YAML) form in the `object` column of the `version` record.  But let's say you wanted to pull out all versions for a particular author; without the metadata you would have to deserialize (reify) each `version` object to see if belonged to the author in question.  Clearly this is inefficient.  Using the metadata you can find just those versions you want:
         
     | 
| 
       618 
659 
     | 
    
         | 
| 
       619 
660 
     | 
    
         
             
            ```ruby
         
     | 
| 
       620 
     | 
    
         
            -
            Version.all(:conditions => ['author_id = ?', author_id])
         
     | 
| 
      
 661 
     | 
    
         
            +
            PaperTrail::Version.all(:conditions => ['author_id = ?', author_id])
         
     | 
| 
       621 
662 
     | 
    
         
             
            ```
         
     | 
| 
       622 
663 
     | 
    
         | 
| 
       623 
664 
     | 
    
         
             
            Note you can pass a symbol as a value in the `meta` hash to signal a method to call.
         
     | 
| 
         @@ -793,48 +834,77 @@ sql> delete from versions where created_at < 2010-06-01; 
     | 
|
| 
       793 
834 
     | 
    
         
             
            ```
         
     | 
| 
       794 
835 
     | 
    
         | 
| 
       795 
836 
     | 
    
         
             
            ```ruby
         
     | 
| 
       796 
     | 
    
         
            -
            >> Version.delete_all ["created_at < ?", 1.week.ago]
         
     | 
| 
      
 837 
     | 
    
         
            +
            >> PaperTrail::Version.delete_all ["created_at < ?", 1.week.ago]
         
     | 
| 
       797 
838 
     | 
    
         
             
            ```
         
     | 
| 
       798 
839 
     | 
    
         | 
| 
       799 
     | 
    
         
            -
            ##  
     | 
| 
      
 840 
     | 
    
         
            +
            ## Testing
         
     | 
| 
       800 
841 
     | 
    
         | 
| 
       801 
     | 
    
         
            -
             
     | 
| 
      
 842 
     | 
    
         
            +
            You may want to turn PaperTrail off to speed up your tests.  See the [Turning PaperTrail Off/On](#turning-papertrail-offon) section above.
         
     | 
| 
       802 
843 
     | 
    
         | 
| 
       803 
     | 
    
         
            -
             
     | 
| 
      
 844 
     | 
    
         
            +
            ### RSpec
         
     | 
| 
       804 
845 
     | 
    
         | 
| 
       805 
     | 
    
         
            -
             
     | 
| 
      
 846 
     | 
    
         
            +
            PaperTrail provides a helper that works with RSpec to make it easier to control when `PaperTrail` during testing. By default, PaperTrail will be
         
     | 
| 
      
 847 
     | 
    
         
            +
            turned off for all tests. When you wish to enable PaperTrail for a test you can either wrap the test in a `with_versioning` block, or pass
         
     | 
| 
      
 848 
     | 
    
         
            +
            in `:versioning => true` option to a spec block, like so:
         
     | 
| 
       806 
849 
     | 
    
         | 
| 
       807 
     | 
    
         
            -
             
     | 
| 
      
 850 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 851 
     | 
    
         
            +
            describe "RSpec test group" do
         
     | 
| 
      
 852 
     | 
    
         
            +
              it 'by default, PaperTrail will be turned off' do
         
     | 
| 
      
 853 
     | 
    
         
            +
                PaperTrail.should_not be_enabled
         
     | 
| 
      
 854 
     | 
    
         
            +
              end
         
     | 
| 
       808 
855 
     | 
    
         | 
| 
       809 
     | 
    
         
            -
             
     | 
| 
      
 856 
     | 
    
         
            +
              with_versioning do
         
     | 
| 
      
 857 
     | 
    
         
            +
                it 'within a `with_versioning` block it will be turned on' do
         
     | 
| 
      
 858 
     | 
    
         
            +
                  PaperTrail.should be_enabled
         
     | 
| 
      
 859 
     | 
    
         
            +
                end
         
     | 
| 
      
 860 
     | 
    
         
            +
              end
         
     | 
| 
       810 
861 
     | 
    
         | 
| 
       811 
     | 
    
         
            -
             
     | 
| 
      
 862 
     | 
    
         
            +
              it 'can be turned on at the `it` or `describe` level like this', :versioning => true do
         
     | 
| 
      
 863 
     | 
    
         
            +
                PaperTrail.should be_enabled
         
     | 
| 
      
 864 
     | 
    
         
            +
              end
         
     | 
| 
      
 865 
     | 
    
         
            +
            end
         
     | 
| 
      
 866 
     | 
    
         
            +
            ```
         
     | 
| 
       812 
867 
     | 
    
         | 
| 
       813 
     | 
    
         
            -
             
     | 
| 
      
 868 
     | 
    
         
            +
            The helper will also reset the `PaperTrail.whodunnit` value to `nil` before each test to help prevent data spillover between tests.
         
     | 
| 
      
 869 
     | 
    
         
            +
            If you are using PaperTrail with Rails, the helper will automatically set the `PaperTrail.controller_info` value to `{}` as well, again, to help prevent data spillover between tests.
         
     | 
| 
       814 
870 
     | 
    
         | 
| 
       815 
     | 
    
         
            -
             
     | 
| 
      
 871 
     | 
    
         
            +
            There is also a `be_versioned` matcher provided by PaperTrail's RSpec helper which can be leveraged like so:
         
     | 
| 
       816 
872 
     | 
    
         | 
| 
       817 
     | 
    
         
            -
             
     | 
| 
      
 873 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 874 
     | 
    
         
            +
            class Widget < ActiveRecord::Base
         
     | 
| 
      
 875 
     | 
    
         
            +
            end
         
     | 
| 
       818 
876 
     | 
    
         | 
| 
       819 
     | 
    
         
            -
             
     | 
| 
      
 877 
     | 
    
         
            +
            describe Widget do
         
     | 
| 
      
 878 
     | 
    
         
            +
              it { should_not be_versioned }
         
     | 
| 
       820 
879 
     | 
    
         | 
| 
      
 880 
     | 
    
         
            +
              describe "add versioning to the `Widget` class" do
         
     | 
| 
      
 881 
     | 
    
         
            +
                before(:all) do
         
     | 
| 
      
 882 
     | 
    
         
            +
                  class Widget < ActiveRecord::Base
         
     | 
| 
      
 883 
     | 
    
         
            +
                    has_paper_trail
         
     | 
| 
      
 884 
     | 
    
         
            +
                  end
         
     | 
| 
      
 885 
     | 
    
         
            +
                end
         
     | 
| 
       821 
886 
     | 
    
         | 
| 
       822 
     | 
    
         
            -
             
     | 
| 
      
 887 
     | 
    
         
            +
                it { should be_versioned }
         
     | 
| 
      
 888 
     | 
    
         
            +
              end
         
     | 
| 
      
 889 
     | 
    
         
            +
            end
         
     | 
| 
      
 890 
     | 
    
         
            +
            ```
         
     | 
| 
       823 
891 
     | 
    
         | 
| 
       824 
     | 
    
         
            -
             
     | 
| 
      
 892 
     | 
    
         
            +
            ### Cucumber
         
     | 
| 
       825 
893 
     | 
    
         | 
| 
       826 
     | 
    
         
            -
             
     | 
| 
      
 894 
     | 
    
         
            +
            PaperTrail provides a helper that works similar to the RSpec helper.
         
     | 
| 
      
 895 
     | 
    
         
            +
            By default, PaperTrail will be turned off for all scenarios by a `before` hook added by the helper.
         
     | 
| 
      
 896 
     | 
    
         
            +
            When you wish to enable PaperTrail for a scenario, you can wrap code in a `with_versioning` block in a step, like so:
         
     | 
| 
       827 
897 
     | 
    
         | 
| 
       828 
898 
     | 
    
         
             
            ```ruby
         
     | 
| 
       829 
     | 
    
         
            -
             
     | 
| 
       830 
     | 
    
         
            -
               
     | 
| 
       831 
     | 
    
         
            -
                PaperTrail 
     | 
| 
       832 
     | 
    
         
            -
                PaperTrail.whodunnit = nil
         
     | 
| 
      
 899 
     | 
    
         
            +
            Given /I want versioning on my model/ do
         
     | 
| 
      
 900 
     | 
    
         
            +
              with_versioning do
         
     | 
| 
      
 901 
     | 
    
         
            +
                # PaperTrail will be turned on for all code inside of this block
         
     | 
| 
       833 
902 
     | 
    
         
             
              end
         
     | 
| 
       834 
903 
     | 
    
         
             
            end
         
     | 
| 
       835 
904 
     | 
    
         
             
            ```
         
     | 
| 
       836 
     | 
    
         
            -
            You may want to turn PaperTrail off to speed up your tests.  See the "Turning PaperTrail Off/On" section above.
         
     | 
| 
       837 
905 
     | 
    
         | 
| 
      
 906 
     | 
    
         
            +
            The helper will also reset the `PaperTrail.whodunnit` value to `nil` before each test to help prevent data spillover between tests.
         
     | 
| 
      
 907 
     | 
    
         
            +
            If you are using PaperTrail with Rails, the helper will automatically set the `PaperTrail.controller_info` value to `{}` as well, again, to help prevent data spillover between tests.
         
     | 
| 
       838 
908 
     | 
    
         | 
| 
       839 
909 
     | 
    
         
             
            ## Articles
         
     | 
| 
       840 
910 
     | 
    
         | 
| 
         @@ -894,6 +964,7 @@ Many thanks to: 
     | 
|
| 
       894 
964 
     | 
    
         
             
            * [Tyler Rick](https://github.com/TylerRick)
         
     | 
| 
       895 
965 
     | 
    
         
             
            * [Bradley Priest](https://github.com/bradleypriest)
         
     | 
| 
       896 
966 
     | 
    
         
             
            * [David Butler](https://github.com/dwbutler)
         
     | 
| 
      
 967 
     | 
    
         
            +
            * [Paul Belt](https://github.com/belt)
         
     | 
| 
       897 
968 
     | 
    
         | 
| 
       898 
969 
     | 
    
         | 
| 
       899 
970 
     | 
    
         
             
            ## Inspirations
         
     | 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -2,8 +2,7 @@ require 'bundler' 
     | 
|
| 
       2 
2 
     | 
    
         
             
            Bundler::GemHelper.install_tasks
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            require 'rake/testtask'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            desc 'Test the paper_trail plugin.'
         
     | 
| 
      
 5 
     | 
    
         
            +
            desc 'Run tests on PaperTrail with Test::Unit.'
         
     | 
| 
       7 
6 
     | 
    
         
             
            Rake::TestTask.new(:test) do |t|
         
     | 
| 
       8 
7 
     | 
    
         
             
              t.libs << 'lib'
         
     | 
| 
       9 
8 
     | 
    
         
             
              t.libs << 'test'
         
     | 
| 
         @@ -11,5 +10,12 @@ Rake::TestTask.new(:test) do |t| 
     | 
|
| 
       11 
10 
     | 
    
         
             
              t.verbose = false
         
     | 
| 
       12 
11 
     | 
    
         
             
            end
         
     | 
| 
       13 
12 
     | 
    
         | 
| 
      
 13 
     | 
    
         
            +
            require 'rspec/core/rake_task'
         
     | 
| 
      
 14 
     | 
    
         
            +
            desc 'Run PaperTrail specs for the RSpec helper.'
         
     | 
| 
      
 15 
     | 
    
         
            +
            RSpec::Core::RakeTask.new(:spec)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            desc 'Run all available test suites'
         
     | 
| 
      
 18 
     | 
    
         
            +
            task :run_all_tests => [:test, :spec]
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
       14 
20 
     | 
    
         
             
            desc 'Default: run unit tests.'
         
     | 
| 
       15 
     | 
    
         
            -
            task :default => : 
     | 
| 
      
 21 
     | 
    
         
            +
            task :default => :run_all_tests
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            source 'https://rubygems.org'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            gem 'activerecord', '~> 3.0'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            group :development, :test do
         
     | 
| 
      
 6 
     | 
    
         
            +
              gem 'rake'
         
     | 
| 
      
 7 
     | 
    
         
            +
              gem 'shoulda', '~> 3.5'
         
     | 
| 
      
 8 
     | 
    
         
            +
              gem 'ffaker',  '>= 1.15'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              # Testing of Rails
         
     | 
| 
      
 11 
     | 
    
         
            +
              gem 'railties', '~> 3.0'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              # Testing of Sinatra
         
     | 
| 
      
 14 
     | 
    
         
            +
              gem 'sinatra', '~> 1.0'
         
     | 
| 
      
 15 
     | 
    
         
            +
              gem 'rack-test', '>= 0.6'
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              # Use sqlite3 gem for regular Ruby
         
     | 
| 
      
 18 
     | 
    
         
            +
              gem 'sqlite3', '~> 1.2', :platform => :ruby
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              # RSpec testing
         
     | 
| 
      
 21 
     | 
    
         
            +
              gem 'rspec-rails', '~> 2.14'
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              platforms :jruby, :ruby_18 do
         
     | 
| 
      
 24 
     | 
    
         
            +
                # shoulda-matchers > 2.0 is not compatible with Ruby18.
         
     | 
| 
      
 25 
     | 
    
         
            +
                # Since we can't specify difference between JRuby 18/19, we need to use shoulda-matchers 1.5 for all JRuby testing.
         
     | 
| 
      
 26 
     | 
    
         
            +
                gem 'shoulda-matchers', '~> 1.5'
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              # Use jRuby's sqlite3 adapter for jRuby
         
     | 
| 
      
 30 
     | 
    
         
            +
              gem 'activerecord-jdbcsqlite3-adapter', '~> 1.2.9', :platform => :jruby
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,11 +1,10 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'rails/generators'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'rails/generators/migration'
         
     | 
| 
       3 
     | 
    
         
            -
            require 'rails/generators/active_record 
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rails/generators/active_record'
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            module PaperTrail
         
     | 
| 
       6 
     | 
    
         
            -
              class InstallGenerator < Rails::Generators::Base
         
     | 
| 
       7 
     | 
    
         
            -
                include Rails::Generators::Migration
         
     | 
| 
       8 
     | 
    
         
            -
                extend ActiveRecord::Generators::Migration
         
     | 
| 
      
 6 
     | 
    
         
            +
              class InstallGenerator < ::Rails::Generators::Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                include ::Rails::Generators::Migration
         
     | 
| 
       9 
8 
     | 
    
         | 
| 
       10 
9 
     | 
    
         
             
                source_root File.expand_path('../templates', __FILE__)
         
     | 
| 
       11 
10 
     | 
    
         
             
                class_option :with_changes, :type => :boolean, :default => false, :desc => "Store changeset (diff) with each version"
         
     | 
| 
         @@ -16,5 +15,9 @@ module PaperTrail 
     | 
|
| 
       16 
15 
     | 
    
         
             
                  migration_template 'create_versions.rb', 'db/migrate/create_versions.rb'
         
     | 
| 
       17 
16 
     | 
    
         
             
                  migration_template 'add_object_changes_column_to_versions.rb', 'db/migrate/add_object_changes_column_to_versions.rb' if options.with_changes?
         
     | 
| 
       18 
17 
     | 
    
         
             
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def self.next_migration_number(dirname)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  ActiveRecord::Generators::Base.next_migration_number(dirname)
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
       19 
22 
     | 
    
         
             
              end
         
     | 
| 
       20 
23 
     | 
    
         
             
            end
         
     | 
    
        data/lib/paper_trail.rb
    CHANGED
    
    | 
         @@ -1,13 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'paper_trail/config'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'paper_trail/controller'
         
     | 
| 
       3 
2 
     | 
    
         
             
            require 'paper_trail/has_paper_trail'
         
     | 
| 
       4 
     | 
    
         
            -
            require 'paper_trail/ 
     | 
| 
      
 3 
     | 
    
         
            +
            require 'paper_trail/cleaner'
         
     | 
| 
       5 
4 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
            # Require all frameworks and serializers
         
     | 
| 
      
 6 
     | 
    
         
            +
            Dir[File.join(File.dirname(__FILE__), 'paper_trail', 'frameworks', '*.rb')].each { |file| require file }
         
     | 
| 
      
 7 
     | 
    
         
            +
            Dir[File.join(File.dirname(__FILE__), 'paper_trail', 'serializers', '*.rb')].each { |file| require file }
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            # PaperTrail's module methods can be called in both models and controllers.
         
     | 
| 
       10 
10 
     | 
    
         
             
            module PaperTrail
         
     | 
| 
      
 11 
     | 
    
         
            +
              extend PaperTrail::Cleaner
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
       12 
13 
     | 
    
         
             
              # Switches PaperTrail on or off.
         
     | 
| 
       13 
14 
     | 
    
         
             
              def self.enabled=(value)
         
     | 
| 
         @@ -78,14 +79,16 @@ module PaperTrail 
     | 
|
| 
       78 
79 
     | 
    
         
             
                PaperTrail.config.serializer
         
     | 
| 
       79 
80 
     | 
    
         
             
              end
         
     | 
| 
       80 
81 
     | 
    
         | 
| 
      
 82 
     | 
    
         
            +
              def self.active_record_protected_attributes?
         
     | 
| 
      
 83 
     | 
    
         
            +
                @active_record_protected_attributes ||= ActiveRecord::VERSION::STRING.to_f < 4.0 || defined?(ProtectedAttributes)
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
       81 
86 
     | 
    
         
             
              private
         
     | 
| 
       82 
87 
     | 
    
         | 
| 
       83 
88 
     | 
    
         
             
              # Thread-safe hash to hold PaperTrail's data.
         
     | 
| 
       84 
89 
     | 
    
         
             
              # Initializing with needed default values.
         
     | 
| 
       85 
90 
     | 
    
         
             
              def self.paper_trail_store
         
     | 
| 
       86 
     | 
    
         
            -
                Thread.current[:paper_trail] ||= {
         
     | 
| 
       87 
     | 
    
         
            -
                  :request_enabled_for_controller => true
         
     | 
| 
       88 
     | 
    
         
            -
                }
         
     | 
| 
      
 91 
     | 
    
         
            +
                Thread.current[:paper_trail] ||= { :request_enabled_for_controller => true }
         
     | 
| 
       89 
92 
     | 
    
         
             
              end
         
     | 
| 
       90 
93 
     | 
    
         | 
| 
       91 
94 
     | 
    
         
             
              # Returns PaperTrail's configuration object.
         
     | 
| 
         @@ -99,11 +102,14 @@ module PaperTrail 
     | 
|
| 
       99 
102 
     | 
    
         | 
| 
       100 
103 
     | 
    
         
             
            end
         
     | 
| 
       101 
104 
     | 
    
         | 
| 
      
 105 
     | 
    
         
            +
            require 'paper_trail/version'
         
     | 
| 
       102 
106 
     | 
    
         | 
| 
       103 
107 
     | 
    
         
             
            ActiveSupport.on_load(:active_record) do
         
     | 
| 
       104 
108 
     | 
    
         
             
              include PaperTrail::Model
         
     | 
| 
       105 
109 
     | 
    
         
             
            end
         
     | 
| 
       106 
110 
     | 
    
         | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
               
     | 
| 
      
 111 
     | 
    
         
            +
            if defined?(ActionController)
         
     | 
| 
      
 112 
     | 
    
         
            +
              ActiveSupport.on_load(:action_controller) do
         
     | 
| 
      
 113 
     | 
    
         
            +
                include PaperTrail::Rails::Controller
         
     | 
| 
      
 114 
     | 
    
         
            +
              end
         
     | 
| 
       109 
115 
     | 
    
         
             
            end
         
     |