paper_trail 9.2.0 → 12.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +20 -0
- data/lib/generators/paper_trail/install/USAGE +3 -0
- data/lib/generators/paper_trail/{install_generator.rb → install/install_generator.rb} +15 -38
- data/lib/generators/paper_trail/{templates → install/templates}/add_object_changes_to_versions.rb.erb +0 -0
- data/lib/generators/paper_trail/{templates → install/templates}/create_versions.rb.erb +5 -3
- 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 +19 -0
- data/lib/paper_trail/attribute_serializers/attribute_serializer_factory.rb +24 -10
- data/lib/paper_trail/attribute_serializers/cast_attribute_serializer.rb +14 -46
- data/lib/paper_trail/compatibility.rb +51 -0
- data/lib/paper_trail/config.rb +9 -2
- data/lib/paper_trail/errors.rb +33 -0
- data/lib/paper_trail/events/base.rb +320 -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 +65 -0
- data/lib/paper_trail/frameworks/active_record.rb +9 -2
- data/lib/paper_trail/frameworks/rails/controller.rb +1 -9
- data/lib/paper_trail/frameworks/rails/railtie.rb +30 -0
- data/lib/paper_trail/frameworks/rails.rb +1 -2
- data/lib/paper_trail/has_paper_trail.rb +20 -17
- data/lib/paper_trail/model_config.rb +127 -87
- data/lib/paper_trail/queries/versions/where_attribute_changes.rb +50 -0
- data/lib/paper_trail/queries/versions/where_object.rb +4 -1
- data/lib/paper_trail/queries/versions/where_object_changes.rb +8 -13
- data/lib/paper_trail/queries/versions/where_object_changes_from.rb +57 -0
- data/lib/paper_trail/queries/versions/where_object_changes_to.rb +57 -0
- data/lib/paper_trail/record_trail.rb +94 -411
- data/lib/paper_trail/reifier.rb +41 -25
- data/lib/paper_trail/request.rb +0 -3
- data/lib/paper_trail/serializers/json.rb +0 -10
- data/lib/paper_trail/serializers/yaml.rb +6 -13
- data/lib/paper_trail/type_serializers/postgres_array_serializer.rb +1 -15
- data/lib/paper_trail/version_concern.rb +142 -61
- data/lib/paper_trail/version_number.rb +1 -1
- data/lib/paper_trail.rb +18 -123
- metadata +147 -56
- data/lib/generators/paper_trail/USAGE +0 -2
- data/lib/paper_trail/frameworks/rails/engine.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d64732632c8d2b579619cb3e4ec4f754a3bd82310f464aa715d79709fc0ba58d
|
4
|
+
data.tar.gz: 245ca1378370715e907ef2c7c9eaad6375a77aef0306729e98c2a046d4cb7c89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85ff44a62d2ca043e38805e510ac7bea9b5b2faba00e3e75b79262404b422730a2810e0e95adc0a30e867dd8d20fa21eb63d0b329908934272a591a14df0ce03
|
7
|
+
data.tar.gz: 8454773dd1a683fed0f79f6464a4d2f9944c399b81e4ce3ec205720a27db17ee4daade6793cddf5fe63e8422c3f6564893721ad02bef6abbd42d8e6e8a881b08
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Andy Stewart, AirBlade Software Ltd.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -1,13 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require "rails/generators/active_record"
|
3
|
+
require_relative "../migration_generator"
|
5
4
|
|
6
5
|
module PaperTrail
|
7
6
|
# Installs PaperTrail in a rails app.
|
8
|
-
class InstallGenerator <
|
9
|
-
include ::Rails::Generators::Migration
|
10
|
-
|
7
|
+
class InstallGenerator < MigrationGenerator
|
11
8
|
# Class names of MySQL adapters.
|
12
9
|
# - `MysqlAdapter` - Used by gems: `mysql`, `activerecord-jdbcmysql-adapter`.
|
13
10
|
# - `Mysql2Adapter` - Used by `mysql2` gem.
|
@@ -25,31 +22,16 @@ module PaperTrail
|
|
25
22
|
)
|
26
23
|
|
27
24
|
desc "Generates (but does not run) a migration to add a versions table." \
|
28
|
-
"
|
25
|
+
" See section 5.c. Generators in README.md for more information."
|
29
26
|
|
30
27
|
def create_migration_file
|
31
|
-
add_paper_trail_migration(
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
protected
|
40
|
-
|
41
|
-
def add_paper_trail_migration(template)
|
42
|
-
migration_dir = File.expand_path("db/migrate")
|
43
|
-
if self.class.migration_exists?(migration_dir, template)
|
44
|
-
::Kernel.warn "Migration already exists: #{template}"
|
45
|
-
else
|
46
|
-
migration_template(
|
47
|
-
"#{template}.rb.erb",
|
48
|
-
"db/migrate/#{template}.rb",
|
49
|
-
item_type_options: item_type_options,
|
50
|
-
migration_version: migration_version,
|
51
|
-
versions_table_options: versions_table_options
|
52
|
-
)
|
28
|
+
add_paper_trail_migration(
|
29
|
+
"create_versions",
|
30
|
+
item_type_options: item_type_options,
|
31
|
+
versions_table_options: versions_table_options
|
32
|
+
)
|
33
|
+
if options.with_changes?
|
34
|
+
add_paper_trail_migration("add_object_changes_to_versions")
|
53
35
|
end
|
54
36
|
end
|
55
37
|
|
@@ -58,15 +40,10 @@ module PaperTrail
|
|
58
40
|
# MySQL 5.6 utf8mb4 limit is 191 chars for keys used in indexes.
|
59
41
|
# See https://github.com/paper-trail-gem/paper_trail/issues/651
|
60
42
|
def item_type_options
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
def migration_version
|
67
|
-
major = ActiveRecord::VERSION::MAJOR
|
68
|
-
if major >= 5
|
69
|
-
"[#{major}.#{ActiveRecord::VERSION::MINOR}]"
|
43
|
+
if mysql?
|
44
|
+
", { null: false, limit: 191 }"
|
45
|
+
else
|
46
|
+
", { null: false }"
|
70
47
|
end
|
71
48
|
end
|
72
49
|
|
@@ -91,7 +68,7 @@ module PaperTrail
|
|
91
68
|
#
|
92
69
|
def versions_table_options
|
93
70
|
if mysql?
|
94
|
-
',
|
71
|
+
', options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci"'
|
95
72
|
else
|
96
73
|
""
|
97
74
|
end
|
File without changes
|
@@ -11,7 +11,7 @@ class CreateVersions < ActiveRecord::Migration<%= migration_version %>
|
|
11
11
|
def change
|
12
12
|
create_table :versions<%= versions_table_options %> do |t|
|
13
13
|
t.string :item_type<%= item_type_options %>
|
14
|
-
t.
|
14
|
+
t.bigint :item_id, null: false
|
15
15
|
t.string :event, null: false
|
16
16
|
t.string :whodunnit
|
17
17
|
t.text :object, limit: TEXT_BYTES
|
@@ -25,10 +25,12 @@ class CreateVersions < ActiveRecord::Migration<%= migration_version %>
|
|
25
25
|
# the `created_at` column.
|
26
26
|
# (https://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html)
|
27
27
|
#
|
28
|
-
# MySQL users should also upgrade to rails 4.2, which is the first
|
28
|
+
# MySQL users should also upgrade to at least rails 4.2, which is the first
|
29
29
|
# version of ActiveRecord with support for fractional seconds in MySQL.
|
30
30
|
# (https://github.com/rails/rails/pull/14359)
|
31
|
-
#
|
31
|
+
#
|
32
|
+
# MySQL users should use the following line for `created_at`
|
33
|
+
# t.datetime :created_at, limit: 6
|
32
34
|
t.datetime :created_at
|
33
35
|
end
|
34
36
|
add_index :versions, %i(item_type item_id)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators"
|
4
|
+
require "rails/generators/active_record"
|
5
|
+
|
6
|
+
module PaperTrail
|
7
|
+
# Basic structure to support a generator that builds a migration
|
8
|
+
class MigrationGenerator < ::Rails::Generators::Base
|
9
|
+
include ::Rails::Generators::Migration
|
10
|
+
|
11
|
+
def self.next_migration_number(dirname)
|
12
|
+
::ActiveRecord::Generators::Base.next_migration_number(dirname)
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def add_paper_trail_migration(template, extra_options = {})
|
18
|
+
migration_dir = File.expand_path("db/migrate")
|
19
|
+
if self.class.migration_exists?(migration_dir, template)
|
20
|
+
::Kernel.warn "Migration already exists: #{template}"
|
21
|
+
else
|
22
|
+
migration_template(
|
23
|
+
"#{template}.rb.erb",
|
24
|
+
"db/migrate/#{template}.rb",
|
25
|
+
{ migration_version: migration_version }.merge(extra_options)
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def migration_version
|
31
|
+
format(
|
32
|
+
"[%d.%d]",
|
33
|
+
ActiveRecord::VERSION::MAJOR,
|
34
|
+
ActiveRecord::VERSION::MINOR
|
35
|
+
)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# This migration updates existing `versions` that have `item_type` that refers to
|
2
|
+
# the base_class, and changes them to refer to the subclass instead.
|
3
|
+
class UpdateVersionsForItemSubtype < ActiveRecord::Migration<%= migration_version %>
|
4
|
+
include ActionView::Helpers::TextHelper
|
5
|
+
def up
|
6
|
+
<%=
|
7
|
+
# Returns class, column, range
|
8
|
+
def self.parse_custom_entry(text)
|
9
|
+
parts = text.split("):")
|
10
|
+
range = parts.last.split("..").map(&:to_i)
|
11
|
+
range = Range.new(range.first, range.last)
|
12
|
+
parts.first.split("(") + [range]
|
13
|
+
end
|
14
|
+
# Running:
|
15
|
+
# rails g paper_trail:update_item_subtype Animal(species):1..4 Plant(genus):42..1337
|
16
|
+
# results in:
|
17
|
+
# # Versions of item_type "Animal" with IDs between 1 and 4 will be updated based on `species`
|
18
|
+
# # Versions of item_type "Plant" with IDs between 42 and 1337 will be updated based on `genus`
|
19
|
+
# hints = {"Animal"=>{1..4=>"species"}, "Plant"=>{42..1337=>"genus"}}
|
20
|
+
hint_descriptions = ""
|
21
|
+
hints = args.inject(Hash.new{|h, k| h[k] = {}}) do |s, v|
|
22
|
+
klass, column, range = parse_custom_entry(v)
|
23
|
+
hint_descriptions << " # Versions of item_type \"#{klass}\" with IDs between #{
|
24
|
+
range.first} and #{range.last} will be updated based on \`#{column}\`\n"
|
25
|
+
s[klass][range] = column
|
26
|
+
s
|
27
|
+
end
|
28
|
+
|
29
|
+
unless hints.empty?
|
30
|
+
"#{hint_descriptions} hints = #{hints.inspect}\n"
|
31
|
+
end
|
32
|
+
%>
|
33
|
+
# Find all ActiveRecord models mentioned in existing versions
|
34
|
+
changes = Hash.new { |h, k| h[k] = [] }
|
35
|
+
model_names = PaperTrail::Version.select(:item_type).distinct
|
36
|
+
model_names.map(&:item_type).each do |model_name|
|
37
|
+
hint = hints[model_name] if defined?(hints)
|
38
|
+
begin
|
39
|
+
klass = model_name.constantize
|
40
|
+
# Actually implements an inheritance_column? (Usually "type")
|
41
|
+
has_inheritance_column = klass.columns.map(&:name).include?(klass.inheritance_column)
|
42
|
+
# Find domain of types stored in PaperTrail versions
|
43
|
+
PaperTrail::Version.where(item_type: model_name, item_subtype: nil).select(:id, :object, :object_changes).each do |obj|
|
44
|
+
if (object_detail = PaperTrail.serializer.load(obj.object || obj.object_changes))
|
45
|
+
is_found = false
|
46
|
+
subtype_name = nil
|
47
|
+
hint&.each do |k, v|
|
48
|
+
if k === obj.id && (subtype_name = object_detail[v])
|
49
|
+
break
|
50
|
+
end
|
51
|
+
end
|
52
|
+
if subtype_name.nil? && has_inheritance_column
|
53
|
+
subtype_name = object_detail[klass.inheritance_column]
|
54
|
+
end
|
55
|
+
if subtype_name
|
56
|
+
subtype_name = subtype_name.last if subtype_name.is_a?(Array)
|
57
|
+
if subtype_name != model_name
|
58
|
+
changes[subtype_name] << obj.id
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
rescue NameError => ex
|
64
|
+
say "Skipping reference to #{model_name}", subitem: true
|
65
|
+
end
|
66
|
+
end
|
67
|
+
changes.each do |k, v|
|
68
|
+
# Update in blocks of up to 100 at a time
|
69
|
+
block_of_ids = []
|
70
|
+
id_count = 0
|
71
|
+
num_updated = 0
|
72
|
+
v.sort.each do |id|
|
73
|
+
block_of_ids << id
|
74
|
+
if (id_count += 1) % 100 == 0
|
75
|
+
num_updated += PaperTrail::Version.where(id: block_of_ids).update_all(item_subtype: k)
|
76
|
+
block_of_ids = []
|
77
|
+
end
|
78
|
+
end
|
79
|
+
num_updated += PaperTrail::Version.where(id: block_of_ids).update_all(item_subtype: k)
|
80
|
+
if num_updated > 0
|
81
|
+
say "Associated #{pluralize(num_updated, 'record')} to #{k}", subitem: true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../migration_generator"
|
4
|
+
|
5
|
+
module PaperTrail
|
6
|
+
# Updates STI entries for PaperTrail
|
7
|
+
class UpdateItemSubtypeGenerator < MigrationGenerator
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
9
|
+
|
10
|
+
desc(
|
11
|
+
"Generates (but does not run) a migration to update item_subtype for "\
|
12
|
+
"STI entries in an existing versions table."
|
13
|
+
)
|
14
|
+
|
15
|
+
def create_migration_file
|
16
|
+
add_paper_trail_migration("update_versions_for_item_subtype", sti_type_options: options)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -8,18 +8,32 @@ module PaperTrail
|
|
8
8
|
# not suited for writing JSON to a text column. This factory
|
9
9
|
# replaces certain default Active Record serializers
|
10
10
|
# with custom PaperTrail ones.
|
11
|
+
#
|
12
|
+
# @api private
|
11
13
|
module AttributeSerializerFactory
|
12
|
-
|
14
|
+
class << self
|
15
|
+
# @api private
|
16
|
+
def for(klass, attr)
|
17
|
+
active_record_serializer = klass.type_for_attribute(attr)
|
18
|
+
if ar_pg_array?(active_record_serializer)
|
19
|
+
TypeSerializers::PostgresArraySerializer.new(
|
20
|
+
active_record_serializer.subtype,
|
21
|
+
active_record_serializer.delimiter
|
22
|
+
)
|
23
|
+
else
|
24
|
+
active_record_serializer
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
13
29
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
else
|
22
|
-
active_record_serializer
|
30
|
+
# @api private
|
31
|
+
def ar_pg_array?(obj)
|
32
|
+
if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array)
|
33
|
+
obj.instance_of?(::ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array)
|
34
|
+
else
|
35
|
+
false
|
36
|
+
end
|
23
37
|
end
|
24
38
|
end
|
25
39
|
end
|
@@ -8,9 +8,6 @@ module PaperTrail
|
|
8
8
|
# The `CastAttributeSerializer` (de)serializes model attribute values. For
|
9
9
|
# example, the string "1.99" serializes into the integer `1` when assigned
|
10
10
|
# to an attribute of type `ActiveRecord::Type::Integer`.
|
11
|
-
#
|
12
|
-
# This implementation depends on the `type_for_attribute` method, which was
|
13
|
-
# introduced in rails 4.2. As of PT 8, we no longer support rails < 4.2.
|
14
11
|
class CastAttributeSerializer
|
15
12
|
def initialize(klass)
|
16
13
|
@klass = klass
|
@@ -30,53 +27,24 @@ module PaperTrail
|
|
30
27
|
def defined_enums
|
31
28
|
@defined_enums ||= (@klass.respond_to?(:defined_enums) ? @klass.defined_enums : {})
|
32
29
|
end
|
33
|
-
end
|
34
|
-
|
35
|
-
if ::ActiveRecord::VERSION::MAJOR >= 5
|
36
|
-
# This implementation uses AR 5's `serialize` and `deserialize`.
|
37
|
-
class CastAttributeSerializer
|
38
|
-
def serialize(attr, val)
|
39
|
-
AttributeSerializerFactory.for(@klass, attr).serialize(val)
|
40
|
-
end
|
41
30
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
31
|
+
def deserialize(attr, val)
|
32
|
+
if defined_enums[attr] && val.is_a?(::String)
|
33
|
+
# Because PT 4 used to save the string version of enums to `object_changes`
|
34
|
+
val
|
35
|
+
elsif PaperTrail::RAILS_GTE_7_0 && val.is_a?(ActiveRecord::Type::Time::Value)
|
36
|
+
# Because Rails 7 time attribute throws a delegation error when you deserialize
|
37
|
+
# it with the factory.
|
38
|
+
# See ActiveRecord::Type::Time::Value crashes when loaded from YAML on rails 7.0
|
39
|
+
# https://github.com/rails/rails/issues/43966
|
40
|
+
val.instance_variable_get(:@time)
|
41
|
+
else
|
42
|
+
AttributeSerializerFactory.for(@klass, attr).deserialize(val)
|
49
43
|
end
|
50
44
|
end
|
51
|
-
else
|
52
|
-
# This implementation uses AR 4.2's `type_cast_for_database`. For
|
53
|
-
# versions of AR < 4.2 we provide an implementation of
|
54
|
-
# `type_cast_for_database` in our shim attribute type classes,
|
55
|
-
# `NoOpAttribute` and `SerializedAttribute`.
|
56
|
-
class CastAttributeSerializer
|
57
|
-
def serialize(attr, val)
|
58
|
-
castable_val = val
|
59
|
-
if defined_enums[attr]
|
60
|
-
# `attr` is an enum. Find the number that corresponds to `val`. If `val` is
|
61
|
-
# a number already, there won't be a corresponding entry, just use `val`.
|
62
|
-
castable_val = defined_enums[attr][val] || val
|
63
|
-
end
|
64
|
-
@klass.type_for_attribute(attr).type_cast_for_database(castable_val)
|
65
|
-
end
|
66
45
|
|
67
|
-
|
68
|
-
|
69
|
-
# Because PT 4 used to save the string version of enums to `object_changes`
|
70
|
-
val
|
71
|
-
else
|
72
|
-
val = @klass.type_for_attribute(attr).type_cast_from_database(val)
|
73
|
-
if defined_enums[attr]
|
74
|
-
defined_enums[attr].key(val)
|
75
|
-
else
|
76
|
-
val
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
46
|
+
def serialize(attr, val)
|
47
|
+
AttributeSerializerFactory.for(@klass, attr).serialize(val)
|
80
48
|
end
|
81
49
|
end
|
82
50
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PaperTrail
|
4
|
+
# Rails does not follow SemVer, makes breaking changes in minor versions.
|
5
|
+
# Breaking changes are expected, and are generally good for the rails
|
6
|
+
# ecosystem. However, they often require dozens of hours to fix, even with the
|
7
|
+
# [help of experts](https://github.com/paper-trail-gem/paper_trail/pull/899).
|
8
|
+
#
|
9
|
+
# It is not safe to assume that a new version of rails will be compatible with
|
10
|
+
# PaperTrail. PT is only compatible with the versions of rails that it is
|
11
|
+
# tested against. See `.github/workflows/test.yml`.
|
12
|
+
#
|
13
|
+
# However, as of
|
14
|
+
# [#1213](https://github.com/paper-trail-gem/paper_trail/pull/1213) our
|
15
|
+
# gemspec allows installation with newer, incompatible rails versions. We hope
|
16
|
+
# this will make it easier for contributors to work on compatibility with
|
17
|
+
# newer rails versions. Most PT users should avoid incompatible rails
|
18
|
+
# versions.
|
19
|
+
module Compatibility
|
20
|
+
ACTIVERECORD_GTE = ">= 5.2" # enforced in gemspec
|
21
|
+
ACTIVERECORD_LT = "< 7.1" # not enforced in gemspec
|
22
|
+
|
23
|
+
E_INCOMPATIBLE_AR = <<-EOS
|
24
|
+
PaperTrail %s is not compatible with ActiveRecord %s. We allow PT
|
25
|
+
contributors to install incompatible versions of ActiveRecord, and this
|
26
|
+
warning can be silenced with an environment variable, but this is a bad
|
27
|
+
idea for normal use. Please install a compatible version of ActiveRecord
|
28
|
+
instead (%s). Please see the discussion in paper_trail/compatibility.rb
|
29
|
+
for details.
|
30
|
+
EOS
|
31
|
+
|
32
|
+
# Normal users need a warning if they accidentally install an incompatible
|
33
|
+
# version of ActiveRecord. Contributors can silence this warning with an
|
34
|
+
# environment variable.
|
35
|
+
def self.check_activerecord(ar_version)
|
36
|
+
raise ::TypeError unless ar_version.instance_of?(::Gem::Version)
|
37
|
+
return if ::ENV["PT_SILENCE_AR_COMPAT_WARNING"].present?
|
38
|
+
req = ::Gem::Requirement.new([ACTIVERECORD_GTE, ACTIVERECORD_LT])
|
39
|
+
unless req.satisfied_by?(ar_version)
|
40
|
+
::Kernel.warn(
|
41
|
+
format(
|
42
|
+
E_INCOMPATIBLE_AR,
|
43
|
+
::PaperTrail.gem_version,
|
44
|
+
ar_version,
|
45
|
+
req
|
46
|
+
)
|
47
|
+
)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/paper_trail/config.rb
CHANGED
@@ -8,8 +8,14 @@ module PaperTrail
|
|
8
8
|
# configuration can be found in `paper_trail.rb`, others in `controller.rb`.
|
9
9
|
class Config
|
10
10
|
include Singleton
|
11
|
-
|
12
|
-
|
11
|
+
|
12
|
+
attr_accessor(
|
13
|
+
:association_reify_error_behaviour,
|
14
|
+
:object_changes_adapter,
|
15
|
+
:serializer,
|
16
|
+
:version_limit,
|
17
|
+
:has_paper_trail_defaults
|
18
|
+
)
|
13
19
|
|
14
20
|
def initialize
|
15
21
|
# Variables which affect all threads, whose access is synchronized.
|
@@ -18,6 +24,7 @@ module PaperTrail
|
|
18
24
|
|
19
25
|
# Variables which affect all threads, whose access is *not* synchronized.
|
20
26
|
@serializer = PaperTrail::Serializers::YAML
|
27
|
+
@has_paper_trail_defaults = {}
|
21
28
|
end
|
22
29
|
|
23
30
|
# Indicates whether PaperTrail is on or off. Default: true.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PaperTrail
|
4
|
+
# Generic PaperTrail exception.
|
5
|
+
# @api public
|
6
|
+
class Error < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
# An unexpected option, perhaps a typo, was passed to a public API method.
|
10
|
+
# @api public
|
11
|
+
class InvalidOption < Error
|
12
|
+
end
|
13
|
+
|
14
|
+
# The application's database schema is not supported.
|
15
|
+
# @api public
|
16
|
+
class UnsupportedSchema < Error
|
17
|
+
end
|
18
|
+
|
19
|
+
# The application's database column type is not supported.
|
20
|
+
# @api public
|
21
|
+
class UnsupportedColumnType < UnsupportedSchema
|
22
|
+
def initialize(method:, expected:, actual:)
|
23
|
+
super(
|
24
|
+
format(
|
25
|
+
"%s expected %s column, got %s",
|
26
|
+
method,
|
27
|
+
expected,
|
28
|
+
actual
|
29
|
+
)
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|