paper_trail 4.2.0 → 5.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 +4 -4
- data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +28 -9
- data/.github/ISSUE_TEMPLATE.md +13 -0
- data/.gitignore +2 -1
- data/.rubocop.yml +100 -0
- data/.rubocop_todo.yml +14 -0
- data/.travis.yml +8 -9
- data/Appraisals +41 -0
- data/CHANGELOG.md +49 -9
- data/Gemfile +1 -1
- data/README.md +130 -109
- data/Rakefile +19 -19
- data/doc/bug_report_template.rb +20 -14
- data/gemfiles/ar3.gemfile +10 -53
- 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 +4 -2
- 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 +39 -5
- data/lib/paper_trail.rb +169 -146
- data/lib/paper_trail/attributes_serialization.rb +89 -17
- data/lib/paper_trail/cleaner.rb +15 -9
- data/lib/paper_trail/config.rb +28 -11
- data/lib/paper_trail/frameworks/active_record.rb +4 -0
- 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/cucumber.rb +1 -0
- data/lib/paper_trail/frameworks/rails.rb +2 -7
- data/lib/paper_trail/frameworks/rails/controller.rb +29 -9
- data/lib/paper_trail/frameworks/rails/engine.rb +7 -1
- data/lib/paper_trail/frameworks/rspec.rb +5 -5
- data/lib/paper_trail/frameworks/rspec/helpers.rb +3 -1
- data/lib/paper_trail/frameworks/sinatra.rb +6 -4
- data/lib/paper_trail/has_paper_trail.rb +199 -106
- data/lib/paper_trail/record_history.rb +1 -3
- data/lib/paper_trail/reifier.rb +297 -118
- data/lib/paper_trail/serializers/json.rb +3 -3
- data/lib/paper_trail/serializers/yaml.rb +27 -8
- data/lib/paper_trail/version_association_concern.rb +3 -1
- data/lib/paper_trail/version_concern.rb +75 -35
- data/lib/paper_trail/version_number.rb +6 -9
- data/paper_trail.gemspec +44 -51
- 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 +12 -12
- data/spec/models/boolit_spec.rb +8 -8
- data/spec/models/callback_modifier_spec.rb +47 -47
- 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 +23 -24
- 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 +10 -10
- 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 +82 -52
- 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 +2 -4
- data/spec/paper_trail/config_spec.rb +10 -29
- 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 +41 -22
- 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 +6 -6
- data/test/dummy/app/models/car.rb +3 -0
- data/test/dummy/app/models/chapter.rb +4 -4
- 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 +4 -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/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 +1 -1
- data/test/dummy/app/models/section.rb +1 -1
- 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.ru +1 -1
- data/test/dummy/config/application.rb +20 -9
- data/test/dummy/config/boot.rb +5 -5
- 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 +1 -2
- 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/db/migrate/20110208155312_set_up_test_tables.rb +120 -74
- data/test/dummy/db/schema.rb +29 -6
- 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 +68 -44
- data/test/time_travel_helper.rb +1 -15
- data/test/unit/associations_test.rb +517 -251
- data/test/unit/cleaner_test.rb +66 -60
- data/test/unit/inheritance_column_test.rb +17 -17
- data/test/unit/model_test.rb +611 -504
- data/test/unit/protected_attrs_test.rb +16 -12
- data/test/unit/serializer_test.rb +44 -43
- data/test/unit/serializers/json_test.rb +17 -18
- 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 +12 -13
- data/test/unit/timestamp_test.rb +10 -12
- data/test/unit/version_test.rb +7 -7
- metadata +92 -40
@@ -1,9 +1,9 @@
|
|
1
1
|
class Chapter < ActiveRecord::Base
|
2
|
-
has_many :sections, :
|
3
|
-
has_many :paragraphs, :
|
2
|
+
has_many :sections, dependent: :destroy
|
3
|
+
has_many :paragraphs, through: :sections
|
4
4
|
|
5
|
-
has_many :quotations, :
|
6
|
-
has_many :citations, :
|
5
|
+
has_many :quotations, dependent: :destroy
|
6
|
+
has_many :citations, through: :quotations
|
7
7
|
|
8
8
|
has_paper_trail
|
9
9
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Person < ActiveRecord::Base
|
2
|
-
has_many :authorships, :
|
3
|
-
has_many :books, :
|
2
|
+
has_many :authorships, foreign_key: :author_id, dependent: :destroy
|
3
|
+
has_many :books, through: :authorships
|
4
4
|
has_paper_trail
|
5
5
|
|
6
6
|
# Convert strings to TimeZone objects when assigned
|
@@ -8,7 +8,7 @@ class Person < ActiveRecord::Base
|
|
8
8
|
if value.is_a? ActiveSupport::TimeZone
|
9
9
|
super
|
10
10
|
else
|
11
|
-
zone = ::Time.find_zone(value)
|
11
|
+
zone = ::Time.find_zone(value) # nil if can't find time zone
|
12
12
|
super zone
|
13
13
|
end
|
14
14
|
end
|
@@ -19,9 +19,9 @@ class Person < ActiveRecord::Base
|
|
19
19
|
def dump(zone)
|
20
20
|
zone.try(:name)
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def load(value)
|
24
|
-
::Time.find_zone
|
24
|
+
::Time.find_zone(value)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -33,6 +33,6 @@ class Person < ActiveRecord::Base
|
|
33
33
|
self.class.load(value)
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
serialize :time_zone, TimeZoneSerializer.new
|
38
38
|
end
|
@@ -7,6 +7,7 @@ class Song < ActiveRecord::Base
|
|
7
7
|
def length=(minutes)
|
8
8
|
write_attribute(:length, minutes.to_i * 60)
|
9
9
|
end
|
10
|
+
|
10
11
|
def length
|
11
12
|
read_attribute(:length) / 60
|
12
13
|
end
|
@@ -14,19 +15,27 @@ class Song < ActiveRecord::Base
|
|
14
15
|
# override attributes hashes like some libraries do
|
15
16
|
def attributes_with_name
|
16
17
|
if name
|
17
|
-
attributes_without_name.merge(:
|
18
|
+
attributes_without_name.merge(name: name)
|
18
19
|
else
|
19
20
|
attributes_without_name
|
20
21
|
end
|
21
22
|
end
|
22
|
-
|
23
|
+
|
24
|
+
# `alias_method_chain` is deprecated in rails 5, but we cannot use the
|
25
|
+
# suggested replacement, `Module#prepend`, because we still support ruby 1.9.
|
26
|
+
alias attributes_without_name attributes
|
27
|
+
alias attributes attributes_with_name
|
23
28
|
|
24
29
|
def changed_attributes_with_name
|
25
30
|
if name
|
26
|
-
changed_attributes_without_name.merge(:
|
31
|
+
changed_attributes_without_name.merge(name: name)
|
27
32
|
else
|
28
33
|
changed_attributes_without_name
|
29
34
|
end
|
30
35
|
end
|
31
|
-
|
36
|
+
|
37
|
+
# `alias_method_chain` is deprecated in rails 5, but we cannot use the
|
38
|
+
# suggested replacement, `Module#prepend`, because we still support ruby 1.9.
|
39
|
+
alias changed_attributes_without_name changed_attributes
|
40
|
+
alias changed_attributes changed_attributes_with_name
|
32
41
|
end
|
@@ -1,3 +1,3 @@
|
|
1
1
|
class Thing < ActiveRecord::Base
|
2
|
-
has_paper_trail :
|
3
|
-
end
|
2
|
+
has_paper_trail save_changes: false
|
3
|
+
end
|
@@ -1,15 +1,16 @@
|
|
1
1
|
class Widget < ActiveRecord::Base
|
2
2
|
has_paper_trail
|
3
3
|
has_one :wotsit
|
4
|
-
has_many :whatchamajiggers, :
|
4
|
+
has_many :whatchamajiggers, as: :owner
|
5
5
|
|
6
|
-
EXCLUDED_NAME =
|
6
|
+
EXCLUDED_NAME = "Biglet".freeze
|
7
7
|
|
8
|
-
validates :name, :
|
8
|
+
validates :name, exclusion: { in: [EXCLUDED_NAME] }
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
# `has_many` syntax for specifying order uses a lambda in Rails 4
|
11
|
+
if ::ActiveRecord::VERSION::MAJOR >= 4
|
12
|
+
has_many :fluxors, -> { order(:name) }
|
12
13
|
else
|
13
|
-
has_many :fluxors, :
|
14
|
+
has_many :fluxors, order: :name
|
14
15
|
end
|
15
16
|
end
|
@@ -1,5 +1,6 @@
|
|
1
|
-
# The purpose of this custom version class is to test the scope methods on the
|
2
|
-
# module. See
|
1
|
+
# The purpose of this custom version class is to test the scope methods on the
|
2
|
+
# VersionConcern::ClassMethods module. See
|
3
|
+
# https://github.com/airblade/paper_trail/issues/295 for more details.
|
3
4
|
class JoinedVersion < PaperTrail::Version
|
4
|
-
default_scope { joins(
|
5
|
+
default_scope { joins("INNER JOIN widgets ON widgets.id = versions.item_id") }
|
5
6
|
end
|
@@ -1,3 +1,3 @@
|
|
1
1
|
class PostVersion < PaperTrail::Version
|
2
|
-
self.table_name =
|
3
|
-
end
|
2
|
+
self.table_name = "post_versions"
|
3
|
+
end
|
data/test/dummy/config.ru
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require File.expand_path(
|
1
|
+
require File.expand_path("../boot", __FILE__)
|
2
2
|
|
3
3
|
# Pick the frameworks you want:
|
4
4
|
require "active_record/railtie"
|
5
5
|
require "action_controller/railtie"
|
6
6
|
|
7
7
|
Bundler.require(:default, Rails.env) if defined?(Bundler)
|
8
|
-
require
|
8
|
+
require "paper_trail"
|
9
9
|
|
10
10
|
module Dummy
|
11
11
|
class Application < Rails::Application
|
@@ -49,19 +49,30 @@ module Dummy
|
|
49
49
|
# This will create an empty whitelist of attributes available for mass-assignment for all models
|
50
50
|
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
|
51
51
|
# parameters by using an attr_accessible or attr_protected declaration.
|
52
|
-
|
52
|
+
if ::PaperTrail.active_record_protected_attributes?
|
53
|
+
config.active_record.whitelist_attributes = false
|
54
|
+
end
|
53
55
|
|
54
|
-
#
|
55
|
-
config.assets.enabled = false
|
56
|
+
# `config.assets` is a `NoMethodError` in rails 5.
|
57
|
+
config.assets.enabled = false if config.respond_to?(:assets)
|
56
58
|
|
57
59
|
# Version of your assets, change this if you want to expire all your assets
|
58
60
|
# config.assets.version = '1.0'
|
59
61
|
|
60
62
|
# Rails 4 key for generating secret key
|
61
|
-
config.secret_key_base =
|
62
|
-
|
63
|
-
#
|
64
|
-
|
63
|
+
config.secret_key_base = "A fox regularly kicked the screaming pile of biscuits."
|
64
|
+
|
65
|
+
# `raise_in_transactional_callbacks` was added in rails 4, then deprecated
|
66
|
+
# in rails 5. Oh, how fickle are the gods.
|
67
|
+
if ActiveRecord.respond_to?(:gem_version)
|
68
|
+
v = ActiveRecord.gem_version
|
69
|
+
if v >= Gem::Version.new("4.2") && v < Gem::Version.new("5.0.0.beta1")
|
70
|
+
config.active_record.raise_in_transactional_callbacks = true
|
71
|
+
end
|
72
|
+
if v >= Gem::Version.new("5.0.0.beta1")
|
73
|
+
config.active_record.time_zone_aware_types = [:datetime]
|
74
|
+
end
|
75
|
+
end
|
65
76
|
|
66
77
|
# Set test order for Test::Unit if possible
|
67
78
|
config.active_support.test_order = :sorted if config.active_support.respond_to?(:test_order=)
|
data/test/dummy/config/boot.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
2
|
-
gemfile = File.expand_path(
|
1
|
+
require "rubygems"
|
2
|
+
gemfile = File.expand_path("../../../../Gemfile", __FILE__)
|
3
3
|
|
4
4
|
if File.exist?(gemfile)
|
5
|
-
ENV[
|
6
|
-
require
|
5
|
+
ENV["BUNDLE_GEMFILE"] = gemfile
|
6
|
+
require "bundler"
|
7
7
|
Bundler.setup
|
8
8
|
end
|
9
9
|
|
10
|
-
|
10
|
+
$LOAD_PATH.unshift File.expand_path("../../../../lib", __FILE__)
|
@@ -10,7 +10,7 @@ Dummy::Application.configure do
|
|
10
10
|
config.eager_load = false
|
11
11
|
|
12
12
|
# Show full error reports and disable caching
|
13
|
-
config.consider_all_requests_local
|
13
|
+
config.consider_all_requests_local = true
|
14
14
|
config.action_controller.perform_caching = false
|
15
15
|
|
16
16
|
# Don't care if the mailer can't send
|
@@ -23,7 +23,9 @@ Dummy::Application.configure do
|
|
23
23
|
config.action_dispatch.best_standards_support = :builtin
|
24
24
|
|
25
25
|
# Raise exception on mass assignment protection for Active Record models
|
26
|
-
|
26
|
+
if ::PaperTrail.active_record_protected_attributes?
|
27
|
+
config.active_record.mass_assignment_sanitizer = :strict
|
28
|
+
end
|
27
29
|
|
28
30
|
# Log the query plan for queries taking more than this (works
|
29
31
|
# with SQLite, MySQL, and PostgreSQL)
|
@@ -37,4 +39,3 @@ Dummy::Application.configure do
|
|
37
39
|
# number of complex assets.
|
38
40
|
config.assets.debug = true
|
39
41
|
end
|
40
|
-
|
@@ -11,7 +11,7 @@ Dummy::Application.configure do
|
|
11
11
|
config.eager_load = true
|
12
12
|
|
13
13
|
# Full error reports are disabled and caching is turned on
|
14
|
-
config.consider_all_requests_local
|
14
|
+
config.consider_all_requests_local = false
|
15
15
|
config.action_controller.perform_caching = true
|
16
16
|
|
17
17
|
# Disable Rails's static asset server (Apache or nginx will already do this)
|
@@ -51,7 +51,8 @@ Dummy::Application.configure do
|
|
51
51
|
# Enable serving of images, stylesheets, and JavaScripts from an asset server
|
52
52
|
# config.action_controller.asset_host = "http://assets.example.com"
|
53
53
|
|
54
|
-
# Precompile additional assets (application.js, application.css, and all
|
54
|
+
# Precompile additional assets (application.js, application.css, and all
|
55
|
+
# non-JS/CSS are already added)
|
55
56
|
# config.assets.precompile += %w( search.js )
|
56
57
|
|
57
58
|
# Disable delivery errors, bad email addresses will be ignored
|
@@ -10,16 +10,24 @@ Dummy::Application.configure do
|
|
10
10
|
# Eager loads all registered namespaces
|
11
11
|
config.eager_load = true
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
if config.respond_to?(:public_file_server)
|
14
|
+
config.public_file_server.enabled = true
|
15
|
+
elsif config.respond_to?(:serve_static_files=)
|
15
16
|
config.serve_static_files = true
|
16
17
|
else
|
17
18
|
config.serve_static_assets = true
|
18
19
|
end
|
19
|
-
|
20
|
+
|
21
|
+
if config.respond_to?(:public_file_server)
|
22
|
+
config.public_file_server.headers = {
|
23
|
+
"Cache-Control" => "public, max-age=3600"
|
24
|
+
}
|
25
|
+
else
|
26
|
+
config.static_cache_control = "public, max-age=3600"
|
27
|
+
end
|
20
28
|
|
21
29
|
# Show full error reports and disable caching
|
22
|
-
config.consider_all_requests_local
|
30
|
+
config.consider_all_requests_local = true
|
23
31
|
config.action_controller.perform_caching = false
|
24
32
|
|
25
33
|
# Raise exceptions instead of rendering exception templates
|
@@ -34,7 +42,9 @@ Dummy::Application.configure do
|
|
34
42
|
# config.action_mailer.delivery_method = :test
|
35
43
|
|
36
44
|
# Raise exception on mass assignment protection for Active Record models
|
37
|
-
|
45
|
+
if ::PaperTrail.active_record_protected_attributes?
|
46
|
+
config.active_record.mass_assignment_sanitizer = :strict
|
47
|
+
end
|
38
48
|
|
39
49
|
# Print deprecation notices to the stderr
|
40
50
|
config.active_support.deprecation = :stderr
|