paper_trail 4.0.0 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/CONTRIBUTING.md +105 -0
- data/.github/ISSUE_TEMPLATE.md +13 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +100 -0
- data/.rubocop_todo.yml +14 -0
- data/.travis.yml +11 -10
- data/Appraisals +37 -0
- data/CHANGELOG.md +173 -8
- data/Gemfile +1 -1
- data/README.md +641 -470
- data/Rakefile +19 -19
- data/doc/bug_report_template.rb +71 -0
- data/doc/warning_about_not_setting_whodunnit.md +32 -0
- data/gemfiles/ar3.gemfile +18 -0
- data/gemfiles/ar4.gemfile +7 -0
- data/gemfiles/ar5.gemfile +13 -0
- data/lib/generators/paper_trail/install_generator.rb +26 -18
- data/lib/generators/paper_trail/templates/add_object_changes_to_versions.rb +3 -1
- data/lib/generators/paper_trail/templates/add_transaction_id_column_to_versions.rb +2 -0
- data/lib/generators/paper_trail/templates/create_version_associations.rb +9 -4
- data/lib/generators/paper_trail/templates/create_versions.rb +53 -5
- data/lib/paper_trail/attribute_serializers/README.md +10 -0
- data/lib/paper_trail/attribute_serializers/cast_attribute_serializer.rb +58 -0
- data/lib/paper_trail/attribute_serializers/legacy_active_record_shim.rb +48 -0
- data/lib/paper_trail/attribute_serializers/object_attribute.rb +39 -0
- data/lib/paper_trail/attribute_serializers/object_changes_attribute.rb +42 -0
- data/lib/paper_trail/cleaner.rb +41 -18
- data/lib/paper_trail/config.rb +42 -26
- data/lib/paper_trail/frameworks/active_record/models/paper_trail/version.rb +5 -1
- data/lib/paper_trail/frameworks/active_record/models/paper_trail/version_association.rb +6 -2
- data/lib/paper_trail/frameworks/active_record.rb +2 -2
- data/lib/paper_trail/frameworks/cucumber.rb +1 -0
- data/lib/paper_trail/frameworks/rails/controller.rb +50 -14
- data/lib/paper_trail/frameworks/rails/engine.rb +6 -1
- data/lib/paper_trail/frameworks/rails.rb +2 -7
- data/lib/paper_trail/frameworks/rspec/helpers.rb +3 -1
- data/lib/paper_trail/frameworks/rspec.rb +5 -5
- data/lib/paper_trail/frameworks/sinatra.rb +8 -5
- data/lib/paper_trail/has_paper_trail.rb +381 -221
- data/lib/paper_trail/record_history.rb +57 -0
- data/lib/paper_trail/reifier.rb +450 -0
- data/lib/paper_trail/serializers/json.rb +7 -7
- data/lib/paper_trail/serializers/yaml.rb +31 -12
- data/lib/paper_trail/version_association_concern.rb +6 -2
- data/lib/paper_trail/version_concern.rb +200 -287
- data/lib/paper_trail/version_number.rb +6 -9
- data/lib/paper_trail.rb +169 -137
- data/paper_trail.gemspec +41 -43
- data/spec/generators/install_generator_spec.rb +24 -25
- data/spec/generators/paper_trail/templates/create_versions_spec.rb +51 -0
- data/spec/models/animal_spec.rb +23 -6
- data/spec/models/boolit_spec.rb +8 -8
- data/spec/models/callback_modifier_spec.rb +96 -0
- data/spec/models/car_spec.rb +13 -0
- data/spec/models/fluxor_spec.rb +3 -3
- data/spec/models/gadget_spec.rb +19 -19
- data/spec/models/joined_version_spec.rb +3 -3
- data/spec/models/json_version_spec.rb +50 -28
- data/spec/models/kitchen/banana_spec.rb +3 -3
- data/spec/models/not_on_update_spec.rb +7 -4
- data/spec/models/post_with_status_spec.rb +13 -3
- data/spec/models/skipper_spec.rb +40 -11
- data/spec/models/thing_spec.rb +4 -4
- data/spec/models/truck_spec.rb +5 -0
- data/spec/models/vehicle_spec.rb +5 -0
- data/spec/models/version_spec.rb +103 -59
- data/spec/models/widget_spec.rb +86 -55
- data/spec/modules/paper_trail_spec.rb +2 -2
- data/spec/modules/version_concern_spec.rb +11 -12
- data/spec/modules/version_number_spec.rb +3 -4
- data/spec/paper_trail/config_spec.rb +33 -0
- data/spec/paper_trail_spec.rb +16 -14
- data/spec/rails_helper.rb +10 -9
- data/spec/requests/articles_spec.rb +11 -7
- data/spec/spec_helper.rb +42 -17
- data/spec/support/alt_db_init.rb +8 -13
- data/test/custom_json_serializer.rb +3 -3
- data/test/dummy/Rakefile +2 -2
- data/test/dummy/app/controllers/application_controller.rb +21 -8
- data/test/dummy/app/controllers/articles_controller.rb +11 -8
- data/test/dummy/app/controllers/widgets_controller.rb +13 -12
- data/test/dummy/app/models/animal.rb +1 -1
- data/test/dummy/app/models/article.rb +19 -11
- data/test/dummy/app/models/authorship.rb +1 -1
- data/test/dummy/app/models/bar_habtm.rb +4 -0
- data/test/dummy/app/models/book.rb +4 -4
- data/test/dummy/app/models/boolit.rb +1 -1
- data/test/dummy/app/models/callback_modifier.rb +45 -0
- data/test/dummy/app/models/car.rb +3 -0
- data/test/dummy/app/models/chapter.rb +9 -0
- data/test/dummy/app/models/citation.rb +5 -0
- data/test/dummy/app/models/customer.rb +1 -1
- data/test/dummy/app/models/document.rb +2 -2
- data/test/dummy/app/models/editor.rb +1 -1
- data/test/dummy/app/models/foo_habtm.rb +5 -0
- data/test/dummy/app/models/fruit.rb +2 -2
- data/test/dummy/app/models/gadget.rb +1 -1
- data/test/dummy/app/models/kitchen/banana.rb +1 -1
- data/test/dummy/app/models/legacy_widget.rb +2 -2
- data/test/dummy/app/models/line_item.rb +1 -1
- data/test/dummy/app/models/not_on_update.rb +1 -1
- data/test/dummy/app/models/paragraph.rb +5 -0
- data/test/dummy/app/models/person.rb +6 -6
- data/test/dummy/app/models/post.rb +1 -1
- data/test/dummy/app/models/post_with_status.rb +1 -1
- data/test/dummy/app/models/quotation.rb +5 -0
- data/test/dummy/app/models/section.rb +6 -0
- data/test/dummy/app/models/skipper.rb +2 -2
- data/test/dummy/app/models/song.rb +13 -4
- data/test/dummy/app/models/thing.rb +2 -2
- data/test/dummy/app/models/translation.rb +2 -2
- data/test/dummy/app/models/truck.rb +4 -0
- data/test/dummy/app/models/vehicle.rb +4 -0
- data/test/dummy/app/models/whatchamajigger.rb +1 -1
- data/test/dummy/app/models/widget.rb +7 -6
- data/test/dummy/app/versions/joined_version.rb +4 -3
- data/test/dummy/app/versions/json_version.rb +1 -1
- data/test/dummy/app/versions/kitchen/banana_version.rb +1 -1
- data/test/dummy/app/versions/post_version.rb +2 -2
- data/test/dummy/config/application.rb +20 -9
- data/test/dummy/config/boot.rb +5 -5
- data/test/dummy/config/database.postgres.yml +1 -1
- data/test/dummy/config/environment.rb +1 -1
- data/test/dummy/config/environments/development.rb +4 -3
- data/test/dummy/config/environments/production.rb +3 -2
- data/test/dummy/config/environments/test.rb +15 -5
- data/test/dummy/config/initializers/backtrace_silencers.rb +4 -2
- data/test/dummy/config/initializers/paper_trail.rb +4 -3
- data/test/dummy/config/initializers/secret_token.rb +3 -1
- data/test/dummy/config/initializers/session_store.rb +1 -1
- data/test/dummy/config/routes.rb +2 -2
- data/test/dummy/config.ru +1 -1
- data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +148 -68
- data/test/dummy/db/schema.rb +119 -31
- data/test/dummy/script/rails +6 -4
- data/test/functional/controller_test.rb +34 -35
- data/test/functional/enabled_for_controller_test.rb +6 -7
- data/test/functional/modular_sinatra_test.rb +43 -38
- data/test/functional/sinatra_test.rb +49 -40
- data/test/functional/thread_safety_test.rb +4 -6
- data/test/paper_trail_test.rb +15 -14
- data/test/test_helper.rb +78 -18
- data/test/time_travel_helper.rb +1 -15
- data/test/unit/associations_test.rb +1016 -0
- data/test/unit/cleaner_test.rb +66 -60
- data/test/unit/inheritance_column_test.rb +19 -19
- data/test/unit/model_test.rb +646 -1071
- data/test/unit/protected_attrs_test.rb +19 -14
- data/test/unit/serializer_test.rb +44 -43
- data/test/unit/serializers/json_test.rb +28 -21
- data/test/unit/serializers/mixin_json_test.rb +15 -14
- data/test/unit/serializers/mixin_yaml_test.rb +20 -16
- data/test/unit/serializers/yaml_test.rb +16 -14
- data/test/unit/timestamp_test.rb +10 -12
- data/test/unit/version_test.rb +88 -70
- metadata +166 -72
- data/gemfiles/3.0.gemfile +0 -52
@@ -0,0 +1,33 @@
|
|
1
|
+
require "rails_helper"
|
2
|
+
|
3
|
+
module PaperTrail
|
4
|
+
RSpec.describe Config do
|
5
|
+
describe ".instance" do
|
6
|
+
it "returns the singleton instance" do
|
7
|
+
expect { described_class.instance }.to_not raise_error
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe ".new" do
|
12
|
+
it "raises NoMethodError" do
|
13
|
+
expect { described_class.new }.to raise_error(NoMethodError)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "track_associations?" do
|
18
|
+
context "@track_associations is nil" do
|
19
|
+
after do
|
20
|
+
PaperTrail.config.track_associations = true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns false and prints a deprecation warning" do
|
24
|
+
config = described_class.instance
|
25
|
+
config.track_associations = nil
|
26
|
+
expect {
|
27
|
+
expect(config.track_associations?).to eq(false)
|
28
|
+
}.to output(/DEPRECATION WARNING/).to_stderr
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/spec/paper_trail_spec.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
require
|
1
|
+
require "rails_helper"
|
2
2
|
|
3
|
-
describe
|
4
|
-
context
|
5
|
-
it
|
3
|
+
describe PaperTrail do
|
4
|
+
context "default" do
|
5
|
+
it "should have versioning off by default" do
|
6
6
|
expect(PaperTrail).not_to be_enabled
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
|
+
it "should turn versioning on in a `with_versioning` block" do
|
9
10
|
expect(PaperTrail).not_to be_enabled
|
10
11
|
with_versioning do
|
11
12
|
expect(PaperTrail).to be_enabled
|
@@ -16,17 +17,18 @@ describe "PaperTrail RSpec Helper" do
|
|
16
17
|
context "error within `with_versioning` block" do
|
17
18
|
it "should revert the value of `PaperTrail.enabled?` to it's previous state" do
|
18
19
|
expect(PaperTrail).not_to be_enabled
|
19
|
-
expect { with_versioning { raise } }.to raise_error
|
20
|
+
expect { with_versioning { raise } }.to raise_error(RuntimeError)
|
20
21
|
expect(PaperTrail).not_to be_enabled
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
25
|
-
context
|
26
|
-
it
|
26
|
+
context "`versioning: true`", versioning: true do
|
27
|
+
it "should have versioning on by default" do
|
27
28
|
expect(PaperTrail).to be_enabled
|
28
29
|
end
|
29
|
-
|
30
|
+
|
31
|
+
it "should keep versioning on after a with_versioning block" do
|
30
32
|
expect(PaperTrail).to be_enabled
|
31
33
|
with_versioning do
|
32
34
|
expect(PaperTrail).to be_enabled
|
@@ -35,21 +37,21 @@ describe "PaperTrail RSpec Helper" do
|
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
38
|
-
context
|
40
|
+
context "`with_versioning` block at class level" do
|
39
41
|
it { expect(PaperTrail).not_to be_enabled }
|
40
42
|
|
41
43
|
with_versioning do
|
42
|
-
it
|
44
|
+
it "should have versioning on by default" do
|
43
45
|
expect(PaperTrail).to be_enabled
|
44
46
|
end
|
45
47
|
end
|
46
|
-
it
|
48
|
+
it "should not leak the `enabled?` state into successive tests" do
|
47
49
|
expect(PaperTrail).not_to be_enabled
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
51
53
|
describe :whodunnit do
|
52
|
-
before(:all) { PaperTrail.whodunnit =
|
54
|
+
before(:all) { PaperTrail.whodunnit = "foobar" }
|
53
55
|
|
54
56
|
it "should get set to `nil` by default" do
|
55
57
|
expect(PaperTrail.whodunnit).to be_nil
|
@@ -57,7 +59,7 @@ describe "PaperTrail RSpec Helper" do
|
|
57
59
|
end
|
58
60
|
|
59
61
|
describe :controller_info do
|
60
|
-
before(:all) { ::PaperTrail.controller_info = {:
|
62
|
+
before(:all) { ::PaperTrail.controller_info = { foo: "bar" } }
|
61
63
|
|
62
64
|
it "should get set to an empty hash before each test" do
|
63
65
|
expect(PaperTrail.controller_info).to eq({})
|
data/spec/rails_helper.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
2
|
-
ENV["RAILS_ENV"] ||=
|
3
|
-
ENV["DB"] ||=
|
2
|
+
ENV["RAILS_ENV"] ||= "test"
|
3
|
+
ENV["DB"] ||= "sqlite"
|
4
4
|
|
5
|
-
unless File.
|
5
|
+
unless File.exist?(File.expand_path("../../test/dummy/config/database.yml", __FILE__))
|
6
6
|
warn "WARNING: No database.yml detected for the dummy app, please run `rake prepare` first"
|
7
7
|
end
|
8
8
|
|
9
|
-
require
|
10
|
-
require File.expand_path(
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
9
|
+
require "spec_helper"
|
10
|
+
require File.expand_path("../../test/dummy/config/environment", __FILE__)
|
11
|
+
require "rspec/rails"
|
12
|
+
require "paper_trail/frameworks/rspec"
|
13
|
+
require "shoulda/matchers"
|
14
|
+
require "ffaker"
|
15
|
+
require "timecop"
|
15
16
|
|
16
17
|
# prevent Test::Unit's AutoRunner from executing during RSpec's rake task
|
17
18
|
Test::Unit.run = true if defined?(Test::Unit) && Test::Unit.respond_to?(:run=)
|
@@ -1,14 +1,16 @@
|
|
1
|
-
require
|
1
|
+
require "rails_helper"
|
2
2
|
|
3
|
-
describe "Articles management", :
|
4
|
-
let(:valid_params) { { :
|
3
|
+
describe "Articles management", type: :request, order: :defined do
|
4
|
+
let(:valid_params) { { article: { title: "Doh", content: FFaker::Lorem.sentence } } }
|
5
5
|
|
6
6
|
context "versioning disabled" do
|
7
7
|
specify { expect(PaperTrail).not_to be_enabled }
|
8
8
|
|
9
9
|
it "should not create a version" do
|
10
10
|
expect(PaperTrail).to be_enabled_for_controller
|
11
|
-
expect {
|
11
|
+
expect {
|
12
|
+
post articles_path, params_wrapper(valid_params)
|
13
|
+
}.to_not change(PaperTrail::Version, :count)
|
12
14
|
end
|
13
15
|
|
14
16
|
it "should not leak the state of the `PaperTrail.enabled_for_controller?` into the next test" do
|
@@ -21,9 +23,11 @@ describe "Articles management", :type => :request, :order => :defined do
|
|
21
23
|
|
22
24
|
context "`current_user` method returns a `String`" do
|
23
25
|
it "should set that value as the `whodunnit`" do
|
24
|
-
expect {
|
25
|
-
|
26
|
-
|
26
|
+
expect {
|
27
|
+
post articles_path, params_wrapper(valid_params)
|
28
|
+
}.to change(PaperTrail::Version, :count).by(1)
|
29
|
+
expect(article.title).to eq("Doh")
|
30
|
+
expect(article.versions.last.whodunnit).to eq("foobar")
|
27
31
|
end
|
28
32
|
end
|
29
33
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "pry-nav"
|
2
|
+
|
1
3
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
4
|
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
5
|
# The generated `.rspec` file contains `--require spec_helper` which will cause this
|
@@ -38,52 +40,75 @@ RSpec.configure do |config|
|
|
38
40
|
mocks.verify_partial_doubles = true
|
39
41
|
end
|
40
42
|
|
41
|
-
#
|
42
|
-
|
43
|
-
|
43
|
+
# Support for disabling `verify_partial_doubles` on specific examples.
|
44
|
+
config.around(:each, verify_stubs: false) do |ex|
|
45
|
+
config.mock_with :rspec do |mocks|
|
46
|
+
mocks.verify_partial_doubles = false
|
47
|
+
ex.run
|
48
|
+
mocks.verify_partial_doubles = true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# The settings below are suggested to provide a good initial experience
|
53
|
+
# with RSpec, but feel free to customize to your heart's content.
|
54
|
+
|
44
55
|
# These two settings work together to allow you to limit a spec run
|
45
56
|
# to individual examples or groups you care about by tagging them with
|
46
57
|
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
47
58
|
# get run.
|
48
|
-
config.filter_run :focus
|
49
|
-
config.run_all_when_everything_filtered = true
|
59
|
+
# config.filter_run :focus
|
60
|
+
# config.run_all_when_everything_filtered = true
|
50
61
|
|
51
62
|
# Limits the available syntax to the non-monkey patched syntax that is recommended.
|
52
63
|
# For more details, see:
|
53
64
|
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
54
65
|
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
55
66
|
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
56
|
-
config.disable_monkey_patching!
|
67
|
+
# config.disable_monkey_patching!
|
57
68
|
|
58
69
|
# This setting enables warnings. It's recommended, but in some cases may
|
59
70
|
# be too noisy due to issues in dependencies.
|
60
|
-
config.warnings = true
|
71
|
+
# config.warnings = true
|
61
72
|
|
62
73
|
# Many RSpec users commonly either run the entire suite or an individual
|
63
74
|
# file, and it's useful to allow more verbose output when running an
|
64
75
|
# individual spec file.
|
65
|
-
if config.files_to_run.one?
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end
|
76
|
+
# if config.files_to_run.one?
|
77
|
+
# # Use the documentation formatter for detailed output,
|
78
|
+
# # unless a formatter has already been configured
|
79
|
+
# # (e.g. via a command-line flag).
|
80
|
+
# config.default_formatter = 'doc'
|
81
|
+
# end
|
71
82
|
|
72
83
|
# Print the 10 slowest examples and example groups at the
|
73
84
|
# end of the spec run, to help surface which specs are running
|
74
85
|
# particularly slow.
|
75
|
-
config.profile_examples = 10
|
86
|
+
# config.profile_examples = 10
|
76
87
|
|
77
88
|
# Run specs in random order to surface order dependencies. If you find an
|
78
89
|
# order dependency and want to debug it, you can fix the order by providing
|
79
90
|
# the seed, which is printed after each run.
|
80
91
|
# --seed 1234
|
81
|
-
config.order = :random
|
92
|
+
# config.order = :random
|
82
93
|
|
83
94
|
# Seed global randomization in this process using the `--seed` CLI option.
|
84
95
|
# Setting this allows you to use `--seed` to deterministically reproduce
|
85
96
|
# test failures related to randomization by passing the same `--seed` value
|
86
97
|
# as the one that triggered the failure.
|
87
|
-
Kernel.srand config.seed
|
88
|
-
|
98
|
+
# Kernel.srand config.seed
|
99
|
+
end
|
100
|
+
|
101
|
+
def active_record_gem_version
|
102
|
+
Gem::Version.new(ActiveRecord::VERSION::STRING)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Wrap args in a hash to support the ActionController::TestCase and
|
106
|
+
# ActionDispatch::Integration HTTP request method switch to keyword args
|
107
|
+
# (see https://github.com/rails/rails/blob/master/actionpack/CHANGELOG.md)
|
108
|
+
def params_wrapper(args)
|
109
|
+
if defined?(::Rails) && active_record_gem_version >= Gem::Version.new("5.0.0.beta1")
|
110
|
+
{ params: args }
|
111
|
+
else
|
112
|
+
args
|
113
|
+
end
|
89
114
|
end
|
data/spec/support/alt_db_init.rb
CHANGED
@@ -2,21 +2,16 @@
|
|
2
2
|
# then defines those namespaces, then establishes the sqlite3 connection for the namespaces
|
3
3
|
# to simulate an application with multiple database connections.
|
4
4
|
|
5
|
-
#Load database yaml to use
|
5
|
+
# Load database yaml to use
|
6
6
|
configs = YAML.load_file("#{Rails.root}/config/database.yml")
|
7
7
|
|
8
|
-
#If we are testing with sqlite make it quick
|
8
|
+
# If we are testing with sqlite make it quick
|
9
9
|
db_directory = "#{Rails.root}/db"
|
10
|
-
|
10
|
+
|
11
|
+
# Set up alternate databases
|
11
12
|
if ENV["DB"] == "sqlite"
|
12
|
-
|
13
|
-
|
14
|
-
FileUtils.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-bar.sqlite3"
|
15
|
-
else
|
16
|
-
require 'ftools'
|
17
|
-
File.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-foo.sqlite3"
|
18
|
-
File.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-bar.sqlite3"
|
19
|
-
end
|
13
|
+
FileUtils.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-foo.sqlite3"
|
14
|
+
FileUtils.cp "#{db_directory}/test.sqlite3", "#{db_directory}/test-bar.sqlite3"
|
20
15
|
end
|
21
16
|
|
22
17
|
module Foo
|
@@ -29,7 +24,7 @@ module Foo
|
|
29
24
|
end
|
30
25
|
|
31
26
|
class Document < Base
|
32
|
-
has_paper_trail :
|
27
|
+
has_paper_trail class_name: "Foo::Version"
|
33
28
|
end
|
34
29
|
end
|
35
30
|
|
@@ -48,7 +43,7 @@ module Bar
|
|
48
43
|
end
|
49
44
|
|
50
45
|
class Document < Base
|
51
|
-
has_paper_trail :
|
46
|
+
has_paper_trail class_name: "Bar::Version"
|
52
47
|
end
|
53
48
|
end
|
54
49
|
|
@@ -4,10 +4,10 @@ module CustomJsonSerializer
|
|
4
4
|
|
5
5
|
def self.load(string)
|
6
6
|
parsed_value = super(string)
|
7
|
-
parsed_value.is_a?(Hash) ? parsed_value.reject { |k,v| k.blank? || v.blank? } : parsed_value
|
7
|
+
parsed_value.is_a?(Hash) ? parsed_value.reject { |k, v| k.blank? || v.blank? } : parsed_value
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.dump(object)
|
11
|
-
object.is_a?(Hash) ? super(object.reject { |
|
11
|
+
object.is_a?(Hash) ? super(object.reject { |_k, v| v.nil? }) : super
|
12
12
|
end
|
13
|
-
end
|
13
|
+
end
|
data/test/dummy/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
2
2
|
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
3
3
|
|
4
|
-
require File.expand_path(
|
5
|
-
require
|
4
|
+
require File.expand_path("../config/application", __FILE__)
|
5
|
+
require "rake"
|
6
6
|
|
7
7
|
Dummy::Application.load_tasks
|
@@ -1,20 +1,33 @@
|
|
1
1
|
class ApplicationController < ActionController::Base
|
2
2
|
protect_from_forgery
|
3
3
|
|
4
|
+
# Rails 5 deprecates `before_filter`
|
5
|
+
name_of_before_callback = respond_to?(:before_action) ? :before_action : :before_filter
|
6
|
+
|
7
|
+
# Some applications and libraries modify `current_user`. Their changes need
|
8
|
+
# to be reflected in `whodunnit`, so the `set_paper_trail_whodunnit` below
|
9
|
+
# must happen after this.
|
10
|
+
send(name_of_before_callback, :modify_current_user)
|
11
|
+
|
12
|
+
# Going forward, we'll no longer add this `before_filter`, requiring people
|
13
|
+
# to do so themselves, allowing them to control the order in which this filter
|
14
|
+
# happens.
|
15
|
+
send(name_of_before_callback, :set_paper_trail_whodunnit)
|
16
|
+
|
4
17
|
def rescue_action(e)
|
5
18
|
raise e
|
6
19
|
end
|
7
20
|
|
8
21
|
# Returns id of hypothetical current user
|
9
|
-
|
10
|
-
@current_user ||= OpenStruct.new(:id => 153).tap do |obj|
|
11
|
-
# Invoking `id` returns the `object_id` value in Ruby18 unless specifically overwritten
|
12
|
-
def obj.id; 153; end if RUBY_VERSION < '1.9'
|
13
|
-
end
|
14
|
-
end
|
22
|
+
attr_reader :current_user
|
15
23
|
|
16
24
|
def info_for_paper_trail
|
17
|
-
{:
|
25
|
+
{ ip: request.remote_ip, user_agent: request.user_agent }
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def modify_current_user
|
31
|
+
@current_user = OpenStruct.new(id: 153)
|
18
32
|
end
|
19
|
-
|
20
33
|
end
|
@@ -1,17 +1,20 @@
|
|
1
1
|
class ArticlesController < ApplicationController
|
2
2
|
def create
|
3
|
-
|
4
|
-
@article = Article.create params[:article]
|
5
|
-
else
|
6
|
-
@article = Article.create params.require(:article).permit!
|
7
|
-
end
|
3
|
+
@article = Article.create article_params
|
8
4
|
head :ok
|
9
5
|
end
|
10
6
|
|
11
7
|
def current_user
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
"foobar"
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def article_params
|
14
|
+
if PaperTrail.active_record_protected_attributes?
|
15
|
+
params[:article]
|
16
|
+
else
|
17
|
+
params.require(:article).permit!
|
15
18
|
end
|
16
19
|
end
|
17
20
|
end
|
@@ -1,25 +1,16 @@
|
|
1
1
|
class WidgetsController < ApplicationController
|
2
|
-
|
3
2
|
def paper_trail_enabled_for_controller
|
4
|
-
request.user_agent !=
|
3
|
+
request.user_agent != "Disable User-Agent"
|
5
4
|
end
|
6
5
|
|
7
6
|
def create
|
8
|
-
|
9
|
-
@widget = Widget.create params[:widget]
|
10
|
-
else
|
11
|
-
@widget = Widget.create params[:widget].permit!
|
12
|
-
end
|
7
|
+
@widget = Widget.create widget_params
|
13
8
|
head :ok
|
14
9
|
end
|
15
10
|
|
16
11
|
def update
|
17
12
|
@widget = Widget.find params[:id]
|
18
|
-
|
19
|
-
@widget.update_attributes params[:widget]
|
20
|
-
else
|
21
|
-
@widget.update_attributes params[:widget].permit!
|
22
|
-
end
|
13
|
+
@widget.update_attributes widget_params
|
23
14
|
head :ok
|
24
15
|
end
|
25
16
|
|
@@ -28,4 +19,14 @@ class WidgetsController < ApplicationController
|
|
28
19
|
@widget.destroy
|
29
20
|
head :ok
|
30
21
|
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def widget_params
|
26
|
+
if PaperTrail.active_record_protected_attributes?
|
27
|
+
params[:widget]
|
28
|
+
else
|
29
|
+
params[:widget].permit!
|
30
|
+
end
|
31
|
+
end
|
31
32
|
end
|
@@ -1,16 +1,24 @@
|
|
1
1
|
class Article < ActiveRecord::Base
|
2
|
-
has_paper_trail
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
2
|
+
has_paper_trail(
|
3
|
+
ignore: [
|
4
|
+
:title, {
|
5
|
+
abstract: proc { |obj|
|
6
|
+
["ignore abstract", "Other abstract"].include? obj.abstract
|
7
|
+
}
|
8
|
+
}
|
9
|
+
],
|
10
|
+
only: [:content, { abstract: proc { |obj| obj.abstract.present? } }],
|
11
|
+
skip: [:file_upload],
|
12
|
+
meta: {
|
13
|
+
answer: 42,
|
14
|
+
action: :action_data_provider_method,
|
15
|
+
question: proc { "31 + 11 = #{31 + 11}" },
|
16
|
+
article_id: proc { |article| article.id },
|
17
|
+
title: :title
|
18
|
+
}
|
19
|
+
)
|
12
20
|
|
13
21
|
def action_data_provider_method
|
14
|
-
|
22
|
+
object_id.to_s
|
15
23
|
end
|
16
24
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
class Book < ActiveRecord::Base
|
2
|
-
has_many :authorships, :
|
3
|
-
has_many :authors, :
|
2
|
+
has_many :authorships, dependent: :destroy
|
3
|
+
has_many :authors, through: :authorships
|
4
4
|
|
5
|
-
has_many :editorships, :
|
6
|
-
has_many :editors, :
|
5
|
+
has_many :editorships, dependent: :destroy
|
6
|
+
has_many :editors, through: :editorships
|
7
7
|
|
8
8
|
has_paper_trail
|
9
9
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class CallbackModifier < ActiveRecord::Base
|
2
|
+
has_paper_trail on: []
|
3
|
+
|
4
|
+
def test_destroy
|
5
|
+
transaction do
|
6
|
+
run_callbacks(:destroy) do
|
7
|
+
self.deleted = true
|
8
|
+
save!
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def flagged_deleted?
|
14
|
+
deleted?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class BeforeDestroyModifier < CallbackModifier
|
19
|
+
has_paper_trail on: []
|
20
|
+
paper_trail_on_destroy :before
|
21
|
+
end
|
22
|
+
|
23
|
+
class AfterDestroyModifier < CallbackModifier
|
24
|
+
has_paper_trail on: []
|
25
|
+
paper_trail_on_destroy :after
|
26
|
+
end
|
27
|
+
|
28
|
+
class NoArgDestroyModifier < CallbackModifier
|
29
|
+
has_paper_trail on: []
|
30
|
+
paper_trail_on_destroy
|
31
|
+
end
|
32
|
+
|
33
|
+
class UpdateModifier < CallbackModifier
|
34
|
+
has_paper_trail on: []
|
35
|
+
paper_trail_on_update
|
36
|
+
end
|
37
|
+
|
38
|
+
class CreateModifier < CallbackModifier
|
39
|
+
has_paper_trail on: []
|
40
|
+
paper_trail_on_create
|
41
|
+
end
|
42
|
+
|
43
|
+
class DefaultModifier < CallbackModifier
|
44
|
+
has_paper_trail
|
45
|
+
end
|