paper_trail 5.2.3 → 11.0.0
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 +5 -5
- data/lib/generators/paper_trail/install/USAGE +3 -0
- data/lib/generators/paper_trail/install/install_generator.rb +75 -0
- data/lib/generators/paper_trail/{templates/add_object_changes_to_versions.rb → install/templates/add_object_changes_to_versions.rb.erb} +1 -1
- data/lib/generators/paper_trail/install/templates/create_versions.rb.erb +36 -0
- data/lib/generators/paper_trail/migration_generator.rb +38 -0
- data/lib/generators/paper_trail/update_item_subtype/USAGE +4 -0
- data/lib/generators/paper_trail/update_item_subtype/templates/update_versions_for_item_subtype.rb.erb +85 -0
- data/lib/generators/paper_trail/update_item_subtype/update_item_subtype_generator.rb +17 -0
- data/lib/paper_trail.rb +82 -130
- data/lib/paper_trail/attribute_serializers/attribute_serializer_factory.rb +27 -0
- data/lib/paper_trail/attribute_serializers/cast_attribute_serializer.rb +15 -44
- data/lib/paper_trail/attribute_serializers/object_attribute.rb +2 -0
- data/lib/paper_trail/attribute_serializers/object_changes_attribute.rb +2 -0
- data/lib/paper_trail/cleaner.rb +3 -1
- data/lib/paper_trail/compatibility.rb +51 -0
- data/lib/paper_trail/config.rb +11 -49
- data/lib/paper_trail/events/base.rb +323 -0
- data/lib/paper_trail/events/create.rb +32 -0
- data/lib/paper_trail/events/destroy.rb +42 -0
- data/lib/paper_trail/events/update.rb +60 -0
- data/lib/paper_trail/frameworks/active_record.rb +2 -1
- data/lib/paper_trail/frameworks/active_record/models/paper_trail/version.rb +8 -3
- data/lib/paper_trail/frameworks/cucumber.rb +5 -3
- data/lib/paper_trail/frameworks/rails.rb +2 -0
- data/lib/paper_trail/frameworks/rails/controller.rb +33 -43
- data/lib/paper_trail/frameworks/rails/engine.rb +34 -1
- data/lib/paper_trail/frameworks/rspec.rb +17 -4
- data/lib/paper_trail/frameworks/rspec/helpers.rb +2 -0
- data/lib/paper_trail/has_paper_trail.rb +22 -310
- data/lib/paper_trail/model_config.rb +157 -109
- data/lib/paper_trail/queries/versions/where_object.rb +65 -0
- data/lib/paper_trail/queries/versions/where_object_changes.rb +75 -0
- data/lib/paper_trail/record_history.rb +3 -9
- data/lib/paper_trail/record_trail.rb +169 -319
- data/lib/paper_trail/reifier.rb +53 -374
- data/lib/paper_trail/request.rb +166 -0
- data/lib/paper_trail/serializers/json.rb +9 -10
- data/lib/paper_trail/serializers/yaml.rb +15 -28
- data/lib/paper_trail/type_serializers/postgres_array_serializer.rb +48 -0
- data/lib/paper_trail/version_concern.rb +160 -155
- data/lib/paper_trail/version_number.rb +12 -4
- metadata +77 -372
- data/.github/CONTRIBUTING.md +0 -109
- data/.github/ISSUE_TEMPLATE.md +0 -13
- data/.gitignore +0 -23
- data/.rspec +0 -2
- data/.rubocop.yml +0 -99
- data/.rubocop_todo.yml +0 -22
- data/.travis.yml +0 -41
- data/Appraisals +0 -38
- data/CHANGELOG.md +0 -560
- data/Gemfile +0 -2
- data/MIT-LICENSE +0 -20
- data/README.md +0 -1654
- data/Rakefile +0 -30
- data/doc/bug_report_template.rb +0 -69
- data/doc/warning_about_not_setting_whodunnit.md +0 -32
- data/gemfiles/ar3.gemfile +0 -19
- data/gemfiles/ar4.gemfile +0 -8
- data/gemfiles/ar5.gemfile +0 -9
- data/lib/generators/paper_trail/USAGE +0 -2
- data/lib/generators/paper_trail/default_initializer.rb +0 -0
- data/lib/generators/paper_trail/install_generator.rb +0 -57
- data/lib/generators/paper_trail/templates/add_transaction_id_column_to_versions.rb +0 -13
- data/lib/generators/paper_trail/templates/create_version_associations.rb +0 -22
- data/lib/generators/paper_trail/templates/create_versions.rb +0 -80
- data/lib/paper_trail/attribute_serializers/legacy_active_record_shim.rb +0 -48
- data/lib/paper_trail/frameworks/active_record/models/paper_trail/version_association.rb +0 -11
- data/lib/paper_trail/frameworks/sinatra.rb +0 -40
- data/lib/paper_trail/version_association_concern.rb +0 -17
- data/paper_trail.gemspec +0 -56
- data/spec/generators/install_generator_spec.rb +0 -66
- data/spec/generators/paper_trail/templates/create_versions_spec.rb +0 -51
- data/spec/models/animal_spec.rb +0 -36
- data/spec/models/boolit_spec.rb +0 -48
- data/spec/models/callback_modifier_spec.rb +0 -96
- data/spec/models/car_spec.rb +0 -13
- data/spec/models/custom_primary_key_record_spec.rb +0 -18
- data/spec/models/fluxor_spec.rb +0 -17
- data/spec/models/gadget_spec.rb +0 -68
- data/spec/models/joined_version_spec.rb +0 -47
- data/spec/models/json_version_spec.rb +0 -102
- data/spec/models/kitchen/banana_spec.rb +0 -14
- data/spec/models/not_on_update_spec.rb +0 -22
- data/spec/models/post_with_status_spec.rb +0 -50
- data/spec/models/skipper_spec.rb +0 -46
- data/spec/models/thing_spec.rb +0 -11
- data/spec/models/truck_spec.rb +0 -5
- data/spec/models/vehicle_spec.rb +0 -5
- data/spec/models/version_spec.rb +0 -272
- data/spec/models/widget_spec.rb +0 -343
- data/spec/modules/paper_trail_spec.rb +0 -27
- data/spec/modules/version_concern_spec.rb +0 -31
- data/spec/modules/version_number_spec.rb +0 -43
- data/spec/paper_trail/config_spec.rb +0 -33
- data/spec/paper_trail_spec.rb +0 -79
- data/spec/rails_helper.rb +0 -34
- data/spec/requests/articles_spec.rb +0 -34
- data/spec/spec_helper.rb +0 -114
- data/spec/support/alt_db_init.rb +0 -54
- data/test/custom_json_serializer.rb +0 -13
- data/test/dummy/Rakefile +0 -7
- data/test/dummy/app/controllers/application_controller.rb +0 -33
- data/test/dummy/app/controllers/articles_controller.rb +0 -20
- data/test/dummy/app/controllers/test_controller.rb +0 -5
- data/test/dummy/app/controllers/widgets_controller.rb +0 -32
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/models/animal.rb +0 -6
- data/test/dummy/app/models/article.rb +0 -24
- data/test/dummy/app/models/authorship.rb +0 -5
- data/test/dummy/app/models/bar_habtm.rb +0 -4
- data/test/dummy/app/models/book.rb +0 -9
- data/test/dummy/app/models/boolit.rb +0 -4
- data/test/dummy/app/models/callback_modifier.rb +0 -45
- data/test/dummy/app/models/car.rb +0 -3
- data/test/dummy/app/models/cat.rb +0 -2
- data/test/dummy/app/models/chapter.rb +0 -9
- data/test/dummy/app/models/citation.rb +0 -5
- data/test/dummy/app/models/custom_primary_key_record.rb +0 -13
- data/test/dummy/app/models/customer.rb +0 -4
- data/test/dummy/app/models/document.rb +0 -4
- data/test/dummy/app/models/dog.rb +0 -2
- data/test/dummy/app/models/editor.rb +0 -4
- data/test/dummy/app/models/editorship.rb +0 -5
- data/test/dummy/app/models/elephant.rb +0 -3
- data/test/dummy/app/models/fluxor.rb +0 -3
- data/test/dummy/app/models/foo_habtm.rb +0 -5
- data/test/dummy/app/models/foo_widget.rb +0 -2
- data/test/dummy/app/models/fruit.rb +0 -5
- data/test/dummy/app/models/gadget.rb +0 -3
- data/test/dummy/app/models/kitchen/banana.rb +0 -5
- data/test/dummy/app/models/legacy_widget.rb +0 -4
- data/test/dummy/app/models/line_item.rb +0 -4
- data/test/dummy/app/models/not_on_update.rb +0 -4
- data/test/dummy/app/models/order.rb +0 -5
- data/test/dummy/app/models/paragraph.rb +0 -5
- data/test/dummy/app/models/person.rb +0 -38
- data/test/dummy/app/models/post.rb +0 -3
- data/test/dummy/app/models/post_with_status.rb +0 -8
- data/test/dummy/app/models/protected_widget.rb +0 -3
- data/test/dummy/app/models/quotation.rb +0 -5
- data/test/dummy/app/models/section.rb +0 -6
- data/test/dummy/app/models/skipper.rb +0 -6
- data/test/dummy/app/models/song.rb +0 -41
- data/test/dummy/app/models/thing.rb +0 -3
- data/test/dummy/app/models/translation.rb +0 -4
- data/test/dummy/app/models/truck.rb +0 -4
- data/test/dummy/app/models/vehicle.rb +0 -4
- data/test/dummy/app/models/whatchamajigger.rb +0 -4
- data/test/dummy/app/models/widget.rb +0 -16
- data/test/dummy/app/models/wotsit.rb +0 -8
- data/test/dummy/app/versions/custom_primary_key_record_version.rb +0 -3
- data/test/dummy/app/versions/joined_version.rb +0 -6
- data/test/dummy/app/versions/json_version.rb +0 -3
- data/test/dummy/app/versions/kitchen/banana_version.rb +0 -5
- data/test/dummy/app/versions/post_version.rb +0 -3
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/config.ru +0 -4
- data/test/dummy/config/application.rb +0 -80
- data/test/dummy/config/boot.rb +0 -10
- data/test/dummy/config/database.mysql.yml +0 -19
- data/test/dummy/config/database.postgres.yml +0 -15
- data/test/dummy/config/database.sqlite.yml +0 -15
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -41
- data/test/dummy/config/environments/production.rb +0 -74
- data/test/dummy/config/environments/test.rb +0 -51
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -9
- data/test/dummy/config/initializers/inflections.rb +0 -10
- data/test/dummy/config/initializers/mime_types.rb +0 -5
- data/test/dummy/config/initializers/paper_trail.rb +0 -9
- data/test/dummy/config/initializers/secret_token.rb +0 -9
- data/test/dummy/config/initializers/session_store.rb +0 -8
- data/test/dummy/config/locales/en.yml +0 -5
- data/test/dummy/config/routes.rb +0 -4
- data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +0 -361
- data/test/dummy/db/schema.rb +0 -288
- data/test/dummy/script/rails +0 -8
- data/test/functional/controller_test.rb +0 -90
- data/test/functional/enabled_for_controller_test.rb +0 -28
- data/test/functional/modular_sinatra_test.rb +0 -46
- data/test/functional/sinatra_test.rb +0 -51
- data/test/functional/thread_safety_test.rb +0 -46
- data/test/test_helper.rb +0 -127
- data/test/time_travel_helper.rb +0 -1
- data/test/unit/associations_test.rb +0 -1016
- data/test/unit/cleaner_test.rb +0 -188
- data/test/unit/inheritance_column_test.rb +0 -43
- data/test/unit/model_test.rb +0 -1489
- data/test/unit/protected_attrs_test.rb +0 -52
- data/test/unit/serializer_test.rb +0 -119
- data/test/unit/serializers/json_test.rb +0 -95
- data/test/unit/serializers/mixin_json_test.rb +0 -37
- data/test/unit/serializers/mixin_yaml_test.rb +0 -53
- data/test/unit/serializers/yaml_test.rb +0 -54
- data/test/unit/timestamp_test.rb +0 -41
- data/test/unit/version_test.rb +0 -119
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "paper_trail/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 "paper_trail/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 "paper_trail/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
|
@@ -1,4 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file only needs to be loaded if the gem is being used outside of Rails,
|
2
4
|
# since otherwise the model(s) will get loaded in via the `Rails::Engine`.
|
3
|
-
require "paper_trail/frameworks/active_record/models/paper_trail/version_association"
|
4
5
|
require "paper_trail/frameworks/active_record/models/paper_trail/version"
|
@@ -1,10 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "paper_trail/version_concern"
|
2
4
|
|
3
5
|
module PaperTrail
|
4
6
|
# This is the default ActiveRecord model provided by PaperTrail. Most simple
|
5
|
-
# applications will
|
6
|
-
#
|
7
|
-
#
|
7
|
+
# applications will use this model as-is, but it is possible to sub-class,
|
8
|
+
# extend, or even do without this model entirely. See documentation section
|
9
|
+
# 6.a. Custom Version Classes.
|
10
|
+
#
|
11
|
+
# The paper_trail-association_tracking gem provides a related model,
|
12
|
+
# `VersionAssociation`.
|
8
13
|
class Version < ::ActiveRecord::Base
|
9
14
|
include PaperTrail::VersionConcern
|
10
15
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# before hook for Cucumber
|
2
4
|
Before do
|
3
5
|
PaperTrail.enabled = false
|
4
|
-
PaperTrail.
|
5
|
-
PaperTrail.whodunnit = nil
|
6
|
-
PaperTrail.controller_info = {} if defined?
|
6
|
+
PaperTrail.request.enabled = true
|
7
|
+
PaperTrail.request.whodunnit = nil
|
8
|
+
PaperTrail.request.controller_info = {} if defined?(::Rails)
|
7
9
|
end
|
8
10
|
|
9
11
|
module PaperTrail
|
@@ -1,27 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module PaperTrail
|
2
4
|
module Rails
|
3
5
|
# Extensions to rails controllers. Provides convenient ways to pass certain
|
4
6
|
# information to the model layer, with `controller_info` and `whodunnit`.
|
5
|
-
# Also includes a convenient on/off switch,
|
7
|
+
# Also includes a convenient on/off switch,
|
8
|
+
# `paper_trail_enabled_for_controller`.
|
6
9
|
module Controller
|
7
|
-
def self.included(
|
8
|
-
|
10
|
+
def self.included(controller)
|
11
|
+
controller.before_action(
|
9
12
|
:set_paper_trail_enabled_for_controller,
|
10
13
|
:set_paper_trail_controller_info
|
11
|
-
|
12
|
-
after = [
|
13
|
-
:warn_about_not_setting_whodunnit
|
14
|
-
]
|
15
|
-
|
16
|
-
if base.respond_to? :before_action
|
17
|
-
# Rails 4+
|
18
|
-
before.map { |sym| base.before_action sym }
|
19
|
-
after.map { |sym| base.after_action sym }
|
20
|
-
else
|
21
|
-
# Rails 3.
|
22
|
-
before.map { |sym| base.before_filter sym }
|
23
|
-
after.map { |sym| base.after_filter sym }
|
24
|
-
end
|
14
|
+
)
|
25
15
|
end
|
26
16
|
|
27
17
|
protected
|
@@ -31,11 +21,11 @@ module PaperTrail
|
|
31
21
|
#
|
32
22
|
# Override this method in your controller to call a different
|
33
23
|
# method, e.g. `current_person`, or anything you like.
|
24
|
+
#
|
25
|
+
# @api public
|
34
26
|
def user_for_paper_trail
|
35
27
|
return unless defined?(current_user)
|
36
|
-
|
37
|
-
rescue NoMethodError
|
38
|
-
current_user
|
28
|
+
current_user.try(:id) || current_user
|
39
29
|
end
|
40
30
|
|
41
31
|
# Returns any information about the controller or request that you
|
@@ -56,6 +46,8 @@ module PaperTrail
|
|
56
46
|
# Use the `:meta` option to
|
57
47
|
# `PaperTrail::Model::ClassMethods.has_paper_trail` to store any extra
|
58
48
|
# model-level data you need.
|
49
|
+
#
|
50
|
+
# @api public
|
59
51
|
def info_for_paper_trail
|
60
52
|
{}
|
61
53
|
end
|
@@ -65,6 +57,15 @@ module PaperTrail
|
|
65
57
|
#
|
66
58
|
# Override this method in your controller to specify when PaperTrail
|
67
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
|
68
69
|
def paper_trail_enabled_for_controller
|
69
70
|
::PaperTrail.enabled?
|
70
71
|
end
|
@@ -73,39 +74,28 @@ module PaperTrail
|
|
73
74
|
|
74
75
|
# Tells PaperTrail whether versions should be saved in the current
|
75
76
|
# request.
|
77
|
+
#
|
78
|
+
# @api public
|
76
79
|
def set_paper_trail_enabled_for_controller
|
77
|
-
::PaperTrail.
|
80
|
+
::PaperTrail.request.enabled = paper_trail_enabled_for_controller
|
78
81
|
end
|
79
82
|
|
80
83
|
# Tells PaperTrail who is responsible for any changes that occur.
|
84
|
+
#
|
85
|
+
# @api public
|
81
86
|
def set_paper_trail_whodunnit
|
82
|
-
|
83
|
-
|
87
|
+
if ::PaperTrail.request.enabled?
|
88
|
+
::PaperTrail.request.whodunnit = user_for_paper_trail
|
89
|
+
end
|
84
90
|
end
|
85
91
|
|
86
92
|
# Tells PaperTrail any information from the controller you want to store
|
87
93
|
# alongside any changes that occur.
|
94
|
+
#
|
95
|
+
# @api public
|
88
96
|
def set_paper_trail_controller_info
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
def warn_about_not_setting_whodunnit
|
93
|
-
return unless ::PaperTrail.enabled_for_controller?
|
94
|
-
|
95
|
-
user_present = user_for_paper_trail.present?
|
96
|
-
whodunnit_blank = ::PaperTrail.whodunnit.blank?
|
97
|
-
if user_present && whodunnit_blank && !@set_paper_trail_whodunnit_called
|
98
|
-
source_file_location = self.class.instance_methods(false).map { |m|
|
99
|
-
self.class.instance_method(m).source_location.first
|
100
|
-
}.uniq.first
|
101
|
-
::Kernel.warn <<-EOS.strip_heredoc
|
102
|
-
#{source_file_location}:
|
103
|
-
user_for_paper_trail is present, but whodunnit has not been set.
|
104
|
-
PaperTrail no longer adds the set_paper_trail_whodunnit callback for
|
105
|
-
you. To continue recording whodunnit, please add this before_action
|
106
|
-
callback to your ApplicationController . For more information,
|
107
|
-
please see https://git.io/vrTsk
|
108
|
-
EOS
|
97
|
+
if ::PaperTrail.request.enabled?
|
98
|
+
::PaperTrail.request.controller_info = info_for_paper_trail
|
109
99
|
end
|
110
100
|
end
|
111
101
|
end
|
@@ -1,12 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module PaperTrail
|
2
4
|
module Rails
|
3
5
|
# See http://guides.rubyonrails.org/engines.html
|
4
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/paper_trail/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/paper_trail/pull/1176 for discussion.
|
23
|
+
EOS
|
24
|
+
private_constant :DPR_RUDELY_ENABLING
|
25
|
+
|
5
26
|
paths["app/models"] << "lib/paper_trail/frameworks/active_record/models"
|
27
|
+
|
28
|
+
# --- Begin deprecated section ---
|
6
29
|
config.paper_trail = ActiveSupport::OrderedOptions.new
|
7
30
|
initializer "paper_trail.initialisation" do |app|
|
8
|
-
|
31
|
+
enable = app.config.paper_trail[:enabled]
|
32
|
+
if enable.nil?
|
33
|
+
unless PaperTrail.enabled?
|
34
|
+
::ActiveSupport::Deprecation.warn(DPR_RUDELY_ENABLING)
|
35
|
+
PaperTrail.enabled = true
|
36
|
+
end
|
37
|
+
else
|
38
|
+
::ActiveSupport::Deprecation.warn(DPR_CONFIG_ENABLED)
|
39
|
+
PaperTrail.enabled = enable
|
40
|
+
end
|
9
41
|
end
|
42
|
+
# --- End deprecated section ---
|
10
43
|
end
|
11
44
|
end
|
12
45
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "rspec/core"
|
2
4
|
require "rspec/matchers"
|
3
5
|
require "paper_trail/frameworks/rspec/helpers"
|
@@ -8,9 +10,9 @@ RSpec.configure do |config|
|
|
8
10
|
|
9
11
|
config.before(:each) do
|
10
12
|
::PaperTrail.enabled = false
|
11
|
-
::PaperTrail.
|
12
|
-
::PaperTrail.whodunnit = nil
|
13
|
-
::PaperTrail.controller_info = {} if defined?(::Rails) && defined?(::RSpec::Rails)
|
13
|
+
::PaperTrail.request.enabled = true
|
14
|
+
::PaperTrail.request.whodunnit = nil
|
15
|
+
::PaperTrail.request.controller_info = {} if defined?(::Rails) && defined?(::RSpec::Rails)
|
14
16
|
end
|
15
17
|
|
16
18
|
config.before(:each, versioning: true) do
|
@@ -25,5 +27,16 @@ end
|
|
25
27
|
|
26
28
|
RSpec::Matchers.define :have_a_version_with do |attributes|
|
27
29
|
# check if the model has a version with the specified attributes
|
28
|
-
match
|
30
|
+
match do |actual|
|
31
|
+
versions_association = actual.class.versions_association_name
|
32
|
+
actual.send(versions_association).where_object(attributes).any?
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
RSpec::Matchers.define :have_a_version_with_changes do |attributes|
|
37
|
+
# check if the model has a version changes with the specified attributes
|
38
|
+
match do |actual|
|
39
|
+
versions_association = actual.class.versions_association_name
|
40
|
+
actual.send(versions_association).where_object_changes(attributes).any?
|
41
|
+
end
|
29
42
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
3
|
require "paper_trail/attribute_serializers/object_attribute"
|
4
4
|
require "paper_trail/attribute_serializers/object_changes_attribute"
|
5
5
|
require "paper_trail/model_config"
|
@@ -23,18 +23,18 @@ module PaperTrail
|
|
23
23
|
# Options:
|
24
24
|
#
|
25
25
|
# - :on - The events to track (optional; defaults to all of them). Set
|
26
|
-
# to an array of `:create`, `:update`, `:destroy` as desired.
|
27
|
-
# - :class_name - The name of a custom Version class
|
28
|
-
#
|
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
29
|
# - :ignore - An array of attributes for which a new `Version` will not be
|
30
|
-
# created if only they change. It can also
|
30
|
+
# created if only they change. It can also accept a Hash as an
|
31
31
|
# argument where the key is the attribute to ignore (a `String` or
|
32
32
|
# `Symbol`), which will only be ignored if the value is a `Proc` which
|
33
33
|
# returns truthily.
|
34
34
|
# - :if, :unless - Procs that allow to specify conditions when to save
|
35
35
|
# versions for an object.
|
36
36
|
# - :only - Inverse of `ignore`. A new `Version` will be created only
|
37
|
-
# for these attributes if supplied it can also
|
37
|
+
# for these attributes if supplied it can also accept a Hash as an
|
38
38
|
# argument where the key is the attribute to track (a `String` or
|
39
39
|
# `Symbol`), which will only be counted if the value is a `Proc` which
|
40
40
|
# returns truthily.
|
@@ -47,328 +47,40 @@ module PaperTrail
|
|
47
47
|
# are called with `self`, i.e. the model with the paper trail). See
|
48
48
|
# `PaperTrail::Controller.info_for_paper_trail` for how to store data
|
49
49
|
# from the controller.
|
50
|
-
# - :versions -
|
51
|
-
#
|
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:`.
|
52
54
|
# - :version - The name to use for the method which returns the version
|
53
55
|
# the instance was reified from. Default is `:version`.
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
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.
|
62
64
|
#
|
63
65
|
# @api public
|
64
66
|
def has_paper_trail(options = {})
|
65
|
-
|
67
|
+
defaults = PaperTrail.config.has_paper_trail_defaults
|
68
|
+
paper_trail.setup(defaults.merge(options))
|
66
69
|
end
|
67
70
|
|
68
71
|
# @api public
|
69
72
|
def paper_trail
|
70
73
|
::PaperTrail::ModelConfig.new(self)
|
71
74
|
end
|
72
|
-
|
73
|
-
# @api private
|
74
|
-
def paper_trail_deprecate(new_method, old_method = nil)
|
75
|
-
old = old_method.nil? ? new_method : old_method
|
76
|
-
msg = format("Use paper_trail.%s instead of %s", new_method, old)
|
77
|
-
::ActiveSupport::Deprecation.warn(msg, caller(2))
|
78
|
-
end
|
79
|
-
|
80
|
-
# @deprecated
|
81
|
-
def paper_trail_on_destroy(*args)
|
82
|
-
paper_trail_deprecate "on_destroy", "paper_trail_on_destroy"
|
83
|
-
paper_trail.on_destroy(*args)
|
84
|
-
end
|
85
|
-
|
86
|
-
# @deprecated
|
87
|
-
def paper_trail_on_update
|
88
|
-
paper_trail_deprecate "on_update", "paper_trail_on_update"
|
89
|
-
paper_trail.on_update
|
90
|
-
end
|
91
|
-
|
92
|
-
# @deprecated
|
93
|
-
def paper_trail_on_create
|
94
|
-
paper_trail_deprecate "on_create", "paper_trail_on_create"
|
95
|
-
paper_trail.on_create
|
96
|
-
end
|
97
|
-
|
98
|
-
# @deprecated
|
99
|
-
def paper_trail_off!
|
100
|
-
paper_trail_deprecate "disable", "paper_trail_off!"
|
101
|
-
paper_trail.disable
|
102
|
-
end
|
103
|
-
|
104
|
-
# @deprecated
|
105
|
-
def paper_trail_on!
|
106
|
-
paper_trail_deprecate "enable", "paper_trail_on!"
|
107
|
-
paper_trail.enable
|
108
|
-
end
|
109
|
-
|
110
|
-
# @deprecated
|
111
|
-
def paper_trail_enabled_for_model?
|
112
|
-
paper_trail_deprecate "enabled?", "paper_trail_enabled_for_model?"
|
113
|
-
paper_trail.enabled?
|
114
|
-
end
|
115
|
-
|
116
|
-
# @deprecated
|
117
|
-
def paper_trail_version_class
|
118
|
-
paper_trail_deprecate "version_class", "paper_trail_version_class"
|
119
|
-
paper_trail.version_class
|
120
|
-
end
|
121
75
|
end
|
122
76
|
|
123
77
|
# Wrap the following methods in a module so we can include them only in the
|
124
78
|
# ActiveRecord models that declare `has_paper_trail`.
|
125
79
|
module InstanceMethods
|
80
|
+
# @api public
|
126
81
|
def paper_trail
|
127
82
|
::PaperTrail::RecordTrail.new(self)
|
128
83
|
end
|
129
|
-
|
130
|
-
# @deprecated
|
131
|
-
def live?
|
132
|
-
self.class.paper_trail_deprecate "live?"
|
133
|
-
paper_trail.live?
|
134
|
-
end
|
135
|
-
|
136
|
-
# @deprecated
|
137
|
-
def paper_trail_originator
|
138
|
-
self.class.paper_trail_deprecate "originator", "paper_trail_originator"
|
139
|
-
paper_trail.originator
|
140
|
-
end
|
141
|
-
|
142
|
-
# @deprecated
|
143
|
-
def originator
|
144
|
-
self.class.paper_trail_deprecate "originator"
|
145
|
-
paper_trail.originator
|
146
|
-
end
|
147
|
-
|
148
|
-
# @deprecated
|
149
|
-
def clear_rolled_back_versions
|
150
|
-
self.class.paper_trail_deprecate "clear_rolled_back_versions"
|
151
|
-
paper_trail.clear_rolled_back_versions
|
152
|
-
end
|
153
|
-
|
154
|
-
# @deprecated
|
155
|
-
def source_version
|
156
|
-
self.class.paper_trail_deprecate "source_version"
|
157
|
-
paper_trail.source_version
|
158
|
-
end
|
159
|
-
|
160
|
-
# @deprecated
|
161
|
-
def version_at(*args)
|
162
|
-
self.class.paper_trail_deprecate "version_at"
|
163
|
-
paper_trail.version_at(*args)
|
164
|
-
end
|
165
|
-
|
166
|
-
# @deprecated
|
167
|
-
def versions_between(start_time, end_time, _reify_options = {})
|
168
|
-
self.class.paper_trail_deprecate "versions_between"
|
169
|
-
paper_trail.versions_between(start_time, end_time)
|
170
|
-
end
|
171
|
-
|
172
|
-
# @deprecated
|
173
|
-
def previous_version
|
174
|
-
self.class.paper_trail_deprecate "previous_version"
|
175
|
-
paper_trail.previous_version
|
176
|
-
end
|
177
|
-
|
178
|
-
# @deprecated
|
179
|
-
def next_version
|
180
|
-
self.class.paper_trail_deprecate "next_version"
|
181
|
-
paper_trail.next_version
|
182
|
-
end
|
183
|
-
|
184
|
-
# @deprecated
|
185
|
-
def paper_trail_enabled_for_model?
|
186
|
-
self.class.paper_trail_deprecate "enabled_for_model?", "paper_trail_enabled_for_model?"
|
187
|
-
paper_trail.enabled_for_model?
|
188
|
-
end
|
189
|
-
|
190
|
-
# @deprecated
|
191
|
-
def without_versioning(method = nil, &block)
|
192
|
-
self.class.paper_trail_deprecate "without_versioning"
|
193
|
-
paper_trail.without_versioning(method, &block)
|
194
|
-
end
|
195
|
-
|
196
|
-
# @deprecated
|
197
|
-
def appear_as_new_record(&block)
|
198
|
-
self.class.paper_trail_deprecate "appear_as_new_record"
|
199
|
-
paper_trail.appear_as_new_record(&block)
|
200
|
-
end
|
201
|
-
|
202
|
-
# @deprecated
|
203
|
-
def whodunnit(value, &block)
|
204
|
-
self.class.paper_trail_deprecate "whodunnit"
|
205
|
-
paper_trail.whodunnit(value, &block)
|
206
|
-
end
|
207
|
-
|
208
|
-
# @deprecated
|
209
|
-
def touch_with_version(name = nil)
|
210
|
-
self.class.paper_trail_deprecate "touch_with_version"
|
211
|
-
paper_trail.touch_with_version(name)
|
212
|
-
end
|
213
|
-
|
214
|
-
# `record_create` is deprecated in favor of `paper_trail.record_create`,
|
215
|
-
# but does not yet print a deprecation warning. When the `after_create`
|
216
|
-
# callback is registered (by ModelConfig#on_create) we still refer to this
|
217
|
-
# method by name, e.g.
|
218
|
-
#
|
219
|
-
# @model_class.after_create :record_create, if: :save_version?
|
220
|
-
#
|
221
|
-
# instead of using the preferred method `paper_trail.record_create`, e.g.
|
222
|
-
#
|
223
|
-
# @model_class.after_create { |r| r.paper_trail.record_create if r.save_version?}
|
224
|
-
#
|
225
|
-
# We still register the callback by name so that, if someone calls
|
226
|
-
# `has_paper_trail` twice, the callback will *not* be registered twice.
|
227
|
-
# Our own test suite calls `has_paper_trail` many times for the same
|
228
|
-
# class.
|
229
|
-
#
|
230
|
-
# In the future, perhaps we should require that users only set up
|
231
|
-
# PT once per class.
|
232
|
-
#
|
233
|
-
# @deprecated
|
234
|
-
def record_create
|
235
|
-
paper_trail.record_create
|
236
|
-
end
|
237
|
-
|
238
|
-
# See deprecation comment for `record_create`
|
239
|
-
# @deprecated
|
240
|
-
def record_update(force = nil)
|
241
|
-
paper_trail.record_update(force)
|
242
|
-
end
|
243
|
-
|
244
|
-
# @deprecated
|
245
|
-
def pt_record_object_changes?
|
246
|
-
self.class.paper_trail_deprecate "record_object_changes?", "pt_record_object_changes?"
|
247
|
-
paper_trail.record_object_changes?
|
248
|
-
end
|
249
|
-
|
250
|
-
# @deprecated
|
251
|
-
def pt_recordable_object
|
252
|
-
self.class.paper_trail_deprecate "recordable_object", "pt_recordable_object"
|
253
|
-
paper_trail.recordable_object
|
254
|
-
end
|
255
|
-
|
256
|
-
# @deprecated
|
257
|
-
def pt_recordable_object_changes
|
258
|
-
self.class.paper_trail_deprecate "recordable_object_changes", "pt_recordable_object_changes"
|
259
|
-
paper_trail.recordable_object_changes
|
260
|
-
end
|
261
|
-
|
262
|
-
# @deprecated
|
263
|
-
def changes_for_paper_trail
|
264
|
-
self.class.paper_trail_deprecate "changes", "changes_for_paper_trail"
|
265
|
-
paper_trail.changes
|
266
|
-
end
|
267
|
-
|
268
|
-
# See deprecation comment for `record_create`
|
269
|
-
# @deprecated
|
270
|
-
def clear_version_instance!
|
271
|
-
paper_trail.clear_version_instance
|
272
|
-
end
|
273
|
-
|
274
|
-
# See deprecation comment for `record_create`
|
275
|
-
# @deprecated
|
276
|
-
def reset_timestamp_attrs_for_update_if_needed!
|
277
|
-
paper_trail.reset_timestamp_attrs_for_update_if_needed
|
278
|
-
end
|
279
|
-
|
280
|
-
# See deprecation comment for `record_create`
|
281
|
-
# @deprecated
|
282
|
-
def record_destroy
|
283
|
-
paper_trail.record_destroy
|
284
|
-
end
|
285
|
-
|
286
|
-
# @deprecated
|
287
|
-
def save_associations(version)
|
288
|
-
self.class.paper_trail_deprecate "save_associations"
|
289
|
-
paper_trail.save_associations(version)
|
290
|
-
end
|
291
|
-
|
292
|
-
# @deprecated
|
293
|
-
def save_associations_belongs_to(version)
|
294
|
-
self.class.paper_trail_deprecate "save_associations_belongs_to"
|
295
|
-
paper_trail.save_associations_belongs_to(version)
|
296
|
-
end
|
297
|
-
|
298
|
-
# @deprecated
|
299
|
-
def save_associations_has_and_belongs_to_many(version)
|
300
|
-
self.class.paper_trail_deprecate(
|
301
|
-
"save_associations_habtm",
|
302
|
-
"save_associations_has_and_belongs_to_many"
|
303
|
-
)
|
304
|
-
paper_trail.save_associations_habtm(version)
|
305
|
-
end
|
306
|
-
|
307
|
-
# @deprecated
|
308
|
-
# @api private
|
309
|
-
def reset_transaction_id
|
310
|
-
::ActiveSupport::Deprecation.warn(
|
311
|
-
"reset_transaction_id is deprecated, use PaperTrail.clear_transaction_id"
|
312
|
-
)
|
313
|
-
PaperTrail.clear_transaction_id
|
314
|
-
end
|
315
|
-
|
316
|
-
# @deprecated
|
317
|
-
# @api private
|
318
|
-
def merge_metadata(data)
|
319
|
-
self.class.paper_trail_deprecate "merge_metadata"
|
320
|
-
paper_trail.merge_metadata(data)
|
321
|
-
end
|
322
|
-
|
323
|
-
# @deprecated
|
324
|
-
def attributes_before_change
|
325
|
-
self.class.paper_trail_deprecate "attributes_before_change"
|
326
|
-
paper_trail.attributes_before_change
|
327
|
-
end
|
328
|
-
|
329
|
-
# @deprecated
|
330
|
-
def object_attrs_for_paper_trail
|
331
|
-
self.class.paper_trail_deprecate "object_attrs_for_paper_trail"
|
332
|
-
paper_trail.object_attrs_for_paper_trail
|
333
|
-
end
|
334
|
-
|
335
|
-
# @deprecated
|
336
|
-
def changed_notably?
|
337
|
-
self.class.paper_trail_deprecate "changed_notably?"
|
338
|
-
paper_trail.changed_notably?
|
339
|
-
end
|
340
|
-
|
341
|
-
# @deprecated
|
342
|
-
def ignored_attr_has_changed?
|
343
|
-
self.class.paper_trail_deprecate "ignored_attr_has_changed?"
|
344
|
-
paper_trail.ignored_attr_has_changed?
|
345
|
-
end
|
346
|
-
|
347
|
-
# @deprecated
|
348
|
-
def notably_changed
|
349
|
-
self.class.paper_trail_deprecate "notably_changed"
|
350
|
-
paper_trail.notably_changed
|
351
|
-
end
|
352
|
-
|
353
|
-
# @deprecated
|
354
|
-
def changed_and_not_ignored
|
355
|
-
self.class.paper_trail_deprecate "changed_and_not_ignored"
|
356
|
-
paper_trail.changed_and_not_ignored
|
357
|
-
end
|
358
|
-
|
359
|
-
# The new method is named "enabled?" for consistency.
|
360
|
-
# @deprecated
|
361
|
-
def paper_trail_switched_on?
|
362
|
-
self.class.paper_trail_deprecate "enabled?", "paper_trail_switched_on?"
|
363
|
-
paper_trail.enabled?
|
364
|
-
end
|
365
|
-
|
366
|
-
# @deprecated
|
367
|
-
# @api private
|
368
|
-
def save_version?
|
369
|
-
self.class.paper_trail_deprecate "save_version?"
|
370
|
-
paper_trail.save_version?
|
371
|
-
end
|
372
84
|
end
|
373
85
|
end
|
374
86
|
end
|