mongo_trails 10.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitattributes +2 -0
- data/.gitignore +1 -0
- data/.travis.yml +13 -0
- data/Appraisals +7 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +62 -0
- data/LICENSE +20 -0
- data/README.md +36 -0
- data/Rakefile +13 -0
- data/gemfiles/rails_5.gemfile +9 -0
- data/gemfiles/rails_5.gemfile.lock +63 -0
- data/gemfiles/rails_6.gemfile +9 -0
- data/gemfiles/rails_6.gemfile.lock +63 -0
- data/lib/mongo_trails.rb +154 -0
- data/lib/mongo_trails/attribute_serializers/README.md +10 -0
- data/lib/mongo_trails/attribute_serializers/attribute_serializer_factory.rb +27 -0
- data/lib/mongo_trails/attribute_serializers/cast_attribute_serializer.rb +51 -0
- data/lib/mongo_trails/attribute_serializers/object_attribute.rb +41 -0
- data/lib/mongo_trails/attribute_serializers/object_changes_attribute.rb +44 -0
- data/lib/mongo_trails/cleaner.rb +60 -0
- data/lib/mongo_trails/compatibility.rb +51 -0
- data/lib/mongo_trails/config.rb +41 -0
- data/lib/mongo_trails/events/base.rb +323 -0
- data/lib/mongo_trails/events/create.rb +32 -0
- data/lib/mongo_trails/events/destroy.rb +42 -0
- data/lib/mongo_trails/events/update.rb +60 -0
- data/lib/mongo_trails/frameworks/cucumber.rb +33 -0
- data/lib/mongo_trails/frameworks/rails.rb +4 -0
- data/lib/mongo_trails/frameworks/rails/controller.rb +109 -0
- data/lib/mongo_trails/frameworks/rails/engine.rb +43 -0
- data/lib/mongo_trails/frameworks/rspec.rb +43 -0
- data/lib/mongo_trails/frameworks/rspec/helpers.rb +29 -0
- data/lib/mongo_trails/has_paper_trail.rb +86 -0
- data/lib/mongo_trails/model_config.rb +249 -0
- data/lib/mongo_trails/mongo_support/config.rb +9 -0
- data/lib/mongo_trails/mongo_support/version.rb +56 -0
- data/lib/mongo_trails/queries/versions/where_object.rb +65 -0
- data/lib/mongo_trails/queries/versions/where_object_changes.rb +75 -0
- data/lib/mongo_trails/record_history.rb +51 -0
- data/lib/mongo_trails/record_trail.rb +304 -0
- data/lib/mongo_trails/reifier.rb +130 -0
- data/lib/mongo_trails/request.rb +166 -0
- data/lib/mongo_trails/serializers/json.rb +46 -0
- data/lib/mongo_trails/serializers/yaml.rb +43 -0
- data/lib/mongo_trails/type_serializers/postgres_array_serializer.rb +48 -0
- data/lib/mongo_trails/version_concern.rb +336 -0
- data/lib/mongo_trails/version_number.rb +23 -0
- data/mongo_trails.gemspec +38 -0
- metadata +180 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mongo_trails/events/base"
|
4
|
+
|
5
|
+
module PaperTrail
|
6
|
+
module Events
|
7
|
+
# See docs in `Base`.
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
class Create < Base
|
11
|
+
# Return attributes of nascent `Version` record.
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
def data
|
15
|
+
data = {
|
16
|
+
item: @record,
|
17
|
+
event: @record.paper_trail_event || "create",
|
18
|
+
whodunnit: PaperTrail.request.whodunnit
|
19
|
+
}
|
20
|
+
if @record.respond_to?(:updated_at)
|
21
|
+
data[:created_at] = @record.updated_at
|
22
|
+
end
|
23
|
+
if record_object_changes? && changed_notably?
|
24
|
+
changes = notable_changes
|
25
|
+
data[:object_changes] = prepare_object_changes(changes)
|
26
|
+
end
|
27
|
+
merge_item_subtype_into(data)
|
28
|
+
merge_metadata_into(data)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mongo_trails/events/base"
|
4
|
+
|
5
|
+
module PaperTrail
|
6
|
+
module Events
|
7
|
+
# See docs in `Base`.
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
class Destroy < Base
|
11
|
+
# Return attributes of nascent `Version` record.
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
def data
|
15
|
+
data = {
|
16
|
+
item_id: @record.id,
|
17
|
+
item_type: @record.class.base_class.name,
|
18
|
+
event: @record.paper_trail_event || "destroy",
|
19
|
+
whodunnit: PaperTrail.request.whodunnit
|
20
|
+
}
|
21
|
+
if record_object?
|
22
|
+
data[:object] = recordable_object(false)
|
23
|
+
end
|
24
|
+
if record_object_changes?
|
25
|
+
data[:object_changes] = prepare_object_changes(notable_changes)
|
26
|
+
end
|
27
|
+
merge_item_subtype_into(data)
|
28
|
+
merge_metadata_into(data)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Rails' implementation (eg. `@record.saved_changes`) returns nothing on
|
34
|
+
# destroy, so we have to build the hash we want.
|
35
|
+
#
|
36
|
+
# @override
|
37
|
+
def changes_in_latest_version
|
38
|
+
@record.attributes.map { |attr, value| [attr, [value, nil]] }.to_h
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mongo_trails/events/base"
|
4
|
+
|
5
|
+
module PaperTrail
|
6
|
+
module Events
|
7
|
+
# See docs in `Base`.
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
class Update < Base
|
11
|
+
# - is_touch - [boolean] - Used in the two situations that are touch-like:
|
12
|
+
# - `after_touch` we call `RecordTrail#record_update`
|
13
|
+
# - force_changes - [Hash] - Only used by `RecordTrail#update_columns`,
|
14
|
+
# because there dirty-tracking is off, so it has to track its own changes.
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
def initialize(record, in_after_callback, is_touch, force_changes)
|
18
|
+
super(record, in_after_callback)
|
19
|
+
@is_touch = is_touch
|
20
|
+
@force_changes = force_changes
|
21
|
+
end
|
22
|
+
|
23
|
+
# Return attributes of nascent `Version` record.
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
def data
|
27
|
+
data = {
|
28
|
+
item: @record,
|
29
|
+
event: @record.paper_trail_event || "update",
|
30
|
+
whodunnit: PaperTrail.request.whodunnit
|
31
|
+
}
|
32
|
+
if @record.respond_to?(:updated_at)
|
33
|
+
data[:created_at] = @record.updated_at
|
34
|
+
end
|
35
|
+
if record_object?
|
36
|
+
data[:object] = recordable_object(@is_touch)
|
37
|
+
end
|
38
|
+
if record_object_changes?
|
39
|
+
changes = @force_changes.nil? ? notable_changes : @force_changes
|
40
|
+
data[:object_changes] = prepare_object_changes(changes)
|
41
|
+
end
|
42
|
+
merge_item_subtype_into(data)
|
43
|
+
merge_metadata_into(data)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# `touch` cannot record `object_changes` because rails' `touch` does not
|
49
|
+
# perform dirty-tracking. Specifically, methods from `Dirty`, like
|
50
|
+
# `saved_changes`, return the same values before and after `touch`.
|
51
|
+
#
|
52
|
+
# See https://github.com/rails/rails/issues/33429
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
def record_object_changes?
|
56
|
+
!@is_touch && super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# before hook for Cucumber
|
4
|
+
Before do
|
5
|
+
PaperTrail.enabled = false
|
6
|
+
PaperTrail.request.enabled = true
|
7
|
+
PaperTrail.request.whodunnit = nil
|
8
|
+
PaperTrail.request.controller_info = {} if defined?(::Rails)
|
9
|
+
end
|
10
|
+
|
11
|
+
module PaperTrail
|
12
|
+
module Cucumber
|
13
|
+
# Helper method for enabling PT in Cucumber features.
|
14
|
+
module Extensions
|
15
|
+
# :call-seq:
|
16
|
+
# with_versioning
|
17
|
+
#
|
18
|
+
# enable versioning for specific blocks
|
19
|
+
|
20
|
+
def with_versioning
|
21
|
+
was_enabled = ::PaperTrail.enabled?
|
22
|
+
::PaperTrail.enabled = true
|
23
|
+
begin
|
24
|
+
yield
|
25
|
+
ensure
|
26
|
+
::PaperTrail.enabled = was_enabled
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
World PaperTrail::Cucumber::Extensions
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PaperTrail
|
4
|
+
module Rails
|
5
|
+
# Extensions to rails controllers. Provides convenient ways to pass certain
|
6
|
+
# information to the model layer, with `controller_info` and `whodunnit`.
|
7
|
+
# Also includes a convenient on/off switch,
|
8
|
+
# `paper_trail_enabled_for_controller`.
|
9
|
+
module Controller
|
10
|
+
def self.included(controller)
|
11
|
+
controller.before_action(
|
12
|
+
:set_paper_trail_enabled_for_controller,
|
13
|
+
:set_paper_trail_controller_info
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
# Returns the user who is responsible for any changes that occur.
|
20
|
+
# By default this calls `current_user` and returns the result.
|
21
|
+
#
|
22
|
+
# Override this method in your controller to call a different
|
23
|
+
# method, e.g. `current_person`, or anything you like.
|
24
|
+
#
|
25
|
+
# @api public
|
26
|
+
def user_for_paper_trail
|
27
|
+
return unless defined?(current_user)
|
28
|
+
current_user.try(:id) || current_user
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns any information about the controller or request that you
|
32
|
+
# want PaperTrail to store alongside any changes that occur. By
|
33
|
+
# default this returns an empty hash.
|
34
|
+
#
|
35
|
+
# Override this method in your controller to return a hash of any
|
36
|
+
# information you need. The hash's keys must correspond to columns
|
37
|
+
# in your `versions` table, so don't forget to add any new columns
|
38
|
+
# you need.
|
39
|
+
#
|
40
|
+
# For example:
|
41
|
+
#
|
42
|
+
# {:ip => request.remote_ip, :user_agent => request.user_agent}
|
43
|
+
#
|
44
|
+
# The columns `ip` and `user_agent` must exist in your `versions` # table.
|
45
|
+
#
|
46
|
+
# Use the `:meta` option to
|
47
|
+
# `PaperTrail::Model::ClassMethods.has_paper_trail` to store any extra
|
48
|
+
# model-level data you need.
|
49
|
+
#
|
50
|
+
# @api public
|
51
|
+
def info_for_paper_trail
|
52
|
+
{}
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns `true` (default) or `false` depending on whether PaperTrail
|
56
|
+
# should be active for the current request.
|
57
|
+
#
|
58
|
+
# Override this method in your controller to specify when PaperTrail
|
59
|
+
# should be off.
|
60
|
+
#
|
61
|
+
# ```
|
62
|
+
# def paper_trail_enabled_for_controller
|
63
|
+
# # Don't omit `super` without a good reason.
|
64
|
+
# super && request.user_agent != 'Disable User-Agent'
|
65
|
+
# end
|
66
|
+
# ```
|
67
|
+
#
|
68
|
+
# @api public
|
69
|
+
def paper_trail_enabled_for_controller
|
70
|
+
::PaperTrail.enabled?
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
# Tells PaperTrail whether versions should be saved in the current
|
76
|
+
# request.
|
77
|
+
#
|
78
|
+
# @api public
|
79
|
+
def set_paper_trail_enabled_for_controller
|
80
|
+
::PaperTrail.request.enabled = paper_trail_enabled_for_controller
|
81
|
+
end
|
82
|
+
|
83
|
+
# Tells PaperTrail who is responsible for any changes that occur.
|
84
|
+
#
|
85
|
+
# @api public
|
86
|
+
def set_paper_trail_whodunnit
|
87
|
+
if ::PaperTrail.request.enabled?
|
88
|
+
::PaperTrail.request.whodunnit = user_for_paper_trail
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Tells PaperTrail any information from the controller you want to store
|
93
|
+
# alongside any changes that occur.
|
94
|
+
#
|
95
|
+
# @api public
|
96
|
+
def set_paper_trail_controller_info
|
97
|
+
if ::PaperTrail.request.enabled?
|
98
|
+
::PaperTrail.request.controller_info = info_for_paper_trail
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
if defined?(::ActionController)
|
106
|
+
::ActiveSupport.on_load(:action_controller) do
|
107
|
+
include ::PaperTrail::Rails::Controller
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PaperTrail
|
4
|
+
module Rails
|
5
|
+
# See http://guides.rubyonrails.org/engines.html
|
6
|
+
class Engine < ::Rails::Engine
|
7
|
+
DPR_CONFIG_ENABLED = <<~EOS.squish.freeze
|
8
|
+
The rails configuration option config.paper_trail.enabled is deprecated.
|
9
|
+
Please use PaperTrail.enabled= instead. People were getting confused
|
10
|
+
that PT has both, specifically regarding *when* each was happening. If
|
11
|
+
you'd like to keep config.paper_trail, join the discussion at
|
12
|
+
https://github.com/paper-trail-gem/mongo_trails/pull/1176
|
13
|
+
EOS
|
14
|
+
private_constant :DPR_CONFIG_ENABLED
|
15
|
+
DPR_RUDELY_ENABLING = <<~EOS.squish.freeze
|
16
|
+
At some point early in the rails boot process, you have set
|
17
|
+
PaperTrail.enabled = false. PT's rails engine is now overriding your
|
18
|
+
setting, and setting it to true. We're not sure why, but this is how PT
|
19
|
+
has worked since 5.0, when the config.paper_trail.enabled option was
|
20
|
+
introduced. This is now deprecated. In the future, PT will not override
|
21
|
+
your setting. See
|
22
|
+
https://github.com/paper-trail-gem/mongo_trails/pull/1176 for discussion.
|
23
|
+
EOS
|
24
|
+
private_constant :DPR_RUDELY_ENABLING
|
25
|
+
|
26
|
+
# --- Begin deprecated section ---
|
27
|
+
config.paper_trail = ActiveSupport::OrderedOptions.new
|
28
|
+
initializer "paper_trail.initialisation" do |app|
|
29
|
+
enable = app.config.paper_trail[:enabled]
|
30
|
+
if enable.nil?
|
31
|
+
unless PaperTrail.enabled?
|
32
|
+
::ActiveSupport::Deprecation.warn(DPR_RUDELY_ENABLING)
|
33
|
+
PaperTrail.enabled = true
|
34
|
+
end
|
35
|
+
else
|
36
|
+
::ActiveSupport::Deprecation.warn(DPR_CONFIG_ENABLED)
|
37
|
+
PaperTrail.enabled = enable
|
38
|
+
end
|
39
|
+
end
|
40
|
+
# --- End deprecated section ---
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rspec/core"
|
4
|
+
require "rspec/matchers"
|
5
|
+
require "mongo_trails/frameworks/rspec/helpers"
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.include ::PaperTrail::RSpec::Helpers::InstanceMethods
|
9
|
+
config.extend ::PaperTrail::RSpec::Helpers::ClassMethods
|
10
|
+
|
11
|
+
config.before(:each) do
|
12
|
+
::Mongoid.purge!
|
13
|
+
::PaperTrail.enabled = false
|
14
|
+
::PaperTrail.request.enabled = true
|
15
|
+
::PaperTrail.request.whodunnit = nil
|
16
|
+
::PaperTrail.request.controller_info = {} if defined?(::Rails) && defined?(::RSpec::Rails)
|
17
|
+
end
|
18
|
+
|
19
|
+
config.before(:each, versioning: true) do
|
20
|
+
::PaperTrail.enabled = true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
RSpec::Matchers.define :be_versioned do
|
25
|
+
# check to see if the model has `has_paper_trail` declared on it
|
26
|
+
match { |actual| actual.is_a?(::PaperTrail::Model::InstanceMethods) }
|
27
|
+
end
|
28
|
+
|
29
|
+
RSpec::Matchers.define :have_a_version_with do |attributes|
|
30
|
+
# check if the model has a version with the specified attributes
|
31
|
+
match do |actual|
|
32
|
+
versions_association = actual.class.versions_association_name
|
33
|
+
actual.send(versions_association).where_object(attributes).any?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
RSpec::Matchers.define :have_a_version_with_changes do |attributes|
|
38
|
+
# check if the model has a version changes with the specified attributes
|
39
|
+
match do |actual|
|
40
|
+
versions_association = actual.class.versions_association_name
|
41
|
+
actual.send(versions_association).where_object_changes(attributes).any?
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PaperTrail
|
4
|
+
module RSpec
|
5
|
+
module Helpers
|
6
|
+
# Included in the RSpec configuration in `frameworks/rspec.rb`
|
7
|
+
module InstanceMethods
|
8
|
+
# enable versioning for specific blocks (at instance-level)
|
9
|
+
def with_versioning
|
10
|
+
was_enabled = ::PaperTrail.enabled?
|
11
|
+
::PaperTrail.enabled = true
|
12
|
+
yield
|
13
|
+
ensure
|
14
|
+
::PaperTrail.enabled = was_enabled
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Extended by the RSpec configuration in `frameworks/rspec.rb`
|
19
|
+
module ClassMethods
|
20
|
+
# enable versioning for specific blocks (at class-level)
|
21
|
+
def with_versioning(&block)
|
22
|
+
context "with versioning", versioning: true do
|
23
|
+
class_exec(&block)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mongo_trails/attribute_serializers/object_attribute"
|
4
|
+
require "mongo_trails/attribute_serializers/object_changes_attribute"
|
5
|
+
require "mongo_trails/model_config"
|
6
|
+
require "mongo_trails/record_trail"
|
7
|
+
|
8
|
+
module PaperTrail
|
9
|
+
# Extensions to `ActiveRecord::Base`. See `frameworks/active_record.rb`.
|
10
|
+
# It is our goal to have the smallest possible footprint here, because
|
11
|
+
# `ActiveRecord::Base` is a very crowded namespace! That is why we introduced
|
12
|
+
# `.paper_trail` and `#paper_trail`.
|
13
|
+
module Model
|
14
|
+
def self.included(base)
|
15
|
+
base.send :extend, ClassMethods
|
16
|
+
end
|
17
|
+
|
18
|
+
# :nodoc:
|
19
|
+
module ClassMethods
|
20
|
+
# Declare this in your model to track every create, update, and destroy.
|
21
|
+
# Each version of the model is available in the `versions` association.
|
22
|
+
#
|
23
|
+
# Options:
|
24
|
+
#
|
25
|
+
# - :on - The events to track (optional; defaults to all of them). Set
|
26
|
+
# to an array of `:create`, `:update`, `:destroy` and `:touch` as desired.
|
27
|
+
# - :class_name (deprecated) - The name of a custom Version class that
|
28
|
+
# includes `PaperTrail::VersionConcern`.
|
29
|
+
# - :ignore - An array of attributes for which a new `Version` will not be
|
30
|
+
# created if only they change. It can also accept a Hash as an
|
31
|
+
# argument where the key is the attribute to ignore (a `String` or
|
32
|
+
# `Symbol`), which will only be ignored if the value is a `Proc` which
|
33
|
+
# returns truthily.
|
34
|
+
# - :if, :unless - Procs that allow to specify conditions when to save
|
35
|
+
# versions for an object.
|
36
|
+
# - :only - Inverse of `ignore`. A new `Version` will be created only
|
37
|
+
# for these attributes if supplied it can also accept a Hash as an
|
38
|
+
# argument where the key is the attribute to track (a `String` or
|
39
|
+
# `Symbol`), which will only be counted if the value is a `Proc` which
|
40
|
+
# returns truthily.
|
41
|
+
# - :skip - Fields to ignore completely. As with `ignore`, updates to
|
42
|
+
# these fields will not create a new `Version`. In addition, these
|
43
|
+
# fields will not be included in the serialized versions of the object
|
44
|
+
# whenever a new `Version` is created.
|
45
|
+
# - :meta - A hash of extra data to store. You must add a column to the
|
46
|
+
# `versions` table for each key. Values are objects or procs (which
|
47
|
+
# are called with `self`, i.e. the model with the paper trail). See
|
48
|
+
# `PaperTrail::Controller.info_for_paper_trail` for how to store data
|
49
|
+
# from the controller.
|
50
|
+
# - :versions - Either,
|
51
|
+
# - A String (deprecated) - The name to use for the versions
|
52
|
+
# association. Default is `:versions`.
|
53
|
+
# - A Hash - options passed to `has_many`, plus `name:` and `scope:`.
|
54
|
+
# - :version - The name to use for the method which returns the version
|
55
|
+
# the instance was reified from. Default is `:version`.
|
56
|
+
#
|
57
|
+
# Plugins like the experimental `paper_trail-association_tracking` gem
|
58
|
+
# may accept additional options.
|
59
|
+
#
|
60
|
+
# You can define a default set of options via the configurable
|
61
|
+
# `PaperTrail.config.has_paper_trail_defaults` hash in your applications
|
62
|
+
# initializer. The hash can contain any of the following options and will
|
63
|
+
# provide an overridable default for all models.
|
64
|
+
#
|
65
|
+
# @api public
|
66
|
+
def has_paper_trail(options = {})
|
67
|
+
defaults = PaperTrail.config.has_paper_trail_defaults
|
68
|
+
paper_trail.setup(defaults.merge(options))
|
69
|
+
end
|
70
|
+
|
71
|
+
# @api public
|
72
|
+
def paper_trail
|
73
|
+
::PaperTrail::ModelConfig.new(self)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Wrap the following methods in a module so we can include them only in the
|
78
|
+
# ActiveRecord models that declare `has_paper_trail`.
|
79
|
+
module InstanceMethods
|
80
|
+
# @api public
|
81
|
+
def paper_trail
|
82
|
+
::PaperTrail::RecordTrail.new(self)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|