paper_trail 11.1.0 → 12.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/paper_trail/install/install_generator.rb +6 -4
- data/lib/paper_trail.rb +12 -38
- data/lib/paper_trail/attribute_serializers/attribute_serializer_factory.rb +24 -10
- data/lib/paper_trail/attribute_serializers/cast_attribute_serializer.rb +4 -10
- data/lib/paper_trail/events/base.rb +14 -36
- data/lib/paper_trail/events/destroy.rb +1 -1
- data/lib/paper_trail/frameworks/active_record.rb +9 -2
- data/lib/paper_trail/frameworks/rails.rb +1 -2
- data/lib/paper_trail/frameworks/rails/controller.rb +0 -6
- data/lib/paper_trail/frameworks/rails/railtie.rb +30 -0
- data/lib/paper_trail/model_config.rb +2 -1
- data/lib/paper_trail/queries/versions/where_object_changes.rb +1 -1
- data/lib/paper_trail/queries/versions/where_object_changes_from.rb +65 -0
- data/lib/paper_trail/record_trail.rb +2 -4
- data/lib/paper_trail/serializers/json.rb +8 -0
- data/lib/paper_trail/serializers/yaml.rb +8 -0
- data/lib/paper_trail/type_serializers/postgres_array_serializer.rb +1 -14
- data/lib/paper_trail/version_concern.rb +18 -7
- data/lib/paper_trail/version_number.rb +2 -2
- metadata +41 -13
- data/Gemfile +0 -4
- data/lib/paper_trail/frameworks/rails/engine.rb +0 -45
- data/paper_trail.gemspec +0 -69
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2ce7f019e3413c485beff4eefa957f759b084fe0d29b0d9f3451b6ba3e4befe
|
4
|
+
data.tar.gz: 3f73870b42c582f683936eee21fe288b17d915d1bfbff5327ac50dd8e9766732
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6134547d0c2c69f94962aea4f868aec8d456bbb0afc4588b9b07971074a8d50476f29a59acb41d3e058dea581678d0c7129d8e92a04c370fa2016dbd6bf544b7
|
7
|
+
data.tar.gz: a6ca4e41cf2f6bce774894a9927dc0b3e4abbcbbdbb39fbf4671d029398f26999ce8927143f1f14279a6ad8aa70194025f5b6e653780560a0cc4870dce9b754e
|
@@ -40,9 +40,11 @@ module PaperTrail
|
|
40
40
|
# MySQL 5.6 utf8mb4 limit is 191 chars for keys used in indexes.
|
41
41
|
# See https://github.com/paper-trail-gem/paper_trail/issues/651
|
42
42
|
def item_type_options
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
if mysql?
|
44
|
+
", { null: false, limit: 191 }"
|
45
|
+
else
|
46
|
+
", { null: false }"
|
47
|
+
end
|
46
48
|
end
|
47
49
|
|
48
50
|
def mysql?
|
@@ -66,7 +68,7 @@ module PaperTrail
|
|
66
68
|
#
|
67
69
|
def versions_table_options
|
68
70
|
if mysql?
|
69
|
-
',
|
71
|
+
', options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci"'
|
70
72
|
else
|
71
73
|
""
|
72
74
|
end
|
data/lib/paper_trail.rb
CHANGED
@@ -8,34 +8,17 @@
|
|
8
8
|
# can revisit this decision.
|
9
9
|
require "active_support/all"
|
10
10
|
|
11
|
-
# AR is required for, eg. has_paper_trail.rb, so we could put this `require` in
|
12
|
-
# all of those files, but it seems easier to troubleshoot if we just make sure
|
13
|
-
# AR is loaded here before loading *any* of PT. See discussion of
|
14
|
-
# performance/simplicity tradeoff for activesupport above.
|
15
|
-
require "active_record"
|
16
|
-
|
17
|
-
require "request_store"
|
18
11
|
require "paper_trail/cleaner"
|
19
12
|
require "paper_trail/compatibility"
|
20
13
|
require "paper_trail/config"
|
21
|
-
require "paper_trail/has_paper_trail"
|
22
14
|
require "paper_trail/record_history"
|
23
|
-
require "paper_trail/reifier"
|
24
15
|
require "paper_trail/request"
|
25
|
-
require "paper_trail/version_concern"
|
26
16
|
require "paper_trail/version_number"
|
27
17
|
require "paper_trail/serializers/json"
|
28
|
-
require "paper_trail/serializers/yaml"
|
29
18
|
|
30
19
|
# An ActiveRecord extension that tracks changes to your models, for auditing or
|
31
20
|
# versioning.
|
32
21
|
module PaperTrail
|
33
|
-
E_RAILS_NOT_LOADED = <<-EOS.squish.freeze
|
34
|
-
PaperTrail has been loaded too early, before rails is loaded. This can
|
35
|
-
happen when another gem defines the ::Rails namespace, then PT is loaded,
|
36
|
-
all before rails is loaded. You may want to reorder your Gemfile, or defer
|
37
|
-
the loading of PT by using `require: false` and a manual require elsewhere.
|
38
|
-
EOS
|
39
22
|
E_TIMESTAMP_FIELD_CONFIG = <<-EOS.squish.freeze
|
40
23
|
PaperTrail.timestamp_field= has been removed, without replacement. It is no
|
41
24
|
longer configurable. The timestamp column in the versions table must now be
|
@@ -126,27 +109,18 @@ module PaperTrail
|
|
126
109
|
end
|
127
110
|
end
|
128
111
|
|
129
|
-
#
|
130
|
-
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
#
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
if defined?(::Rails.application)
|
142
|
-
require "paper_trail/frameworks/rails"
|
143
|
-
else
|
144
|
-
::Kernel.warn(::PaperTrail::E_RAILS_NOT_LOADED)
|
145
|
-
end
|
112
|
+
# PT is built on ActiveRecord, but does not require Rails. If Rails is defined,
|
113
|
+
# our Railtie makes sure not to load the AR-dependent parts of PT until AR is
|
114
|
+
# ready. A typical Rails `application.rb` has:
|
115
|
+
#
|
116
|
+
# ```
|
117
|
+
# require 'rails/all' # Defines `Rails`
|
118
|
+
# Bundler.require(*Rails.groups) # require 'paper_trail' (this file)
|
119
|
+
# ```
|
120
|
+
#
|
121
|
+
# Non-rails applications should take similar care to load AR before PT.
|
122
|
+
if defined?(Rails)
|
123
|
+
require "paper_trail/frameworks/rails"
|
146
124
|
else
|
147
125
|
require "paper_trail/frameworks/active_record"
|
148
126
|
end
|
149
|
-
|
150
|
-
if defined?(::ActiveRecord)
|
151
|
-
::PaperTrail::Compatibility.check_activerecord(::ActiveRecord.gem_version)
|
152
|
-
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,13 +27,6 @@ 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
|
-
# Uses AR 5's `serialize` and `deserialize`.
|
36
|
-
class CastAttributeSerializer
|
37
|
-
def serialize(attr, val)
|
38
|
-
AttributeSerializerFactory.for(@klass, attr).serialize(val)
|
39
|
-
end
|
40
30
|
|
41
31
|
def deserialize(attr, val)
|
42
32
|
if defined_enums[attr] && val.is_a?(::String)
|
@@ -46,6 +36,10 @@ module PaperTrail
|
|
46
36
|
AttributeSerializerFactory.for(@klass, attr).deserialize(val)
|
47
37
|
end
|
48
38
|
end
|
39
|
+
|
40
|
+
def serialize(attr, val)
|
41
|
+
AttributeSerializerFactory.for(@klass, attr).serialize(val)
|
42
|
+
end
|
49
43
|
end
|
50
44
|
end
|
51
45
|
end
|
@@ -22,8 +22,6 @@ module PaperTrail
|
|
22
22
|
#
|
23
23
|
# @api private
|
24
24
|
class Base
|
25
|
-
RAILS_GTE_5_1 = ::ActiveRecord.gem_version >= ::Gem::Version.new("5.1.0.beta1")
|
26
|
-
|
27
25
|
# @api private
|
28
26
|
def initialize(record, in_after_callback)
|
29
27
|
@record = record
|
@@ -51,7 +49,7 @@ module PaperTrail
|
|
51
49
|
#
|
52
50
|
# @api private
|
53
51
|
def attribute_changed_in_latest_version?(attr_name)
|
54
|
-
if @in_after_callback
|
52
|
+
if @in_after_callback
|
55
53
|
@record.saved_change_to_attribute?(attr_name.to_s)
|
56
54
|
else
|
57
55
|
@record.attribute_changed?(attr_name.to_s)
|
@@ -60,30 +58,14 @@ module PaperTrail
|
|
60
58
|
|
61
59
|
# @api private
|
62
60
|
def nonskipped_attributes_before_change(is_touch)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
if @record.class.column_names.include?(k)
|
68
|
-
record_attributes[k] = attribute_in_previous_version(k, is_touch)
|
69
|
-
end
|
61
|
+
record_attributes = @record.attributes.except(*@record.paper_trail_options[:skip])
|
62
|
+
record_attributes.each_key do |k|
|
63
|
+
if @record.class.column_names.include?(k)
|
64
|
+
record_attributes[k] = attribute_in_previous_version(k, is_touch)
|
70
65
|
end
|
71
66
|
end
|
72
67
|
end
|
73
68
|
|
74
|
-
# Rails 5.1 changed the API of `ActiveRecord::Dirty`.
|
75
|
-
# @api private
|
76
|
-
def cache_changed_attributes(&block)
|
77
|
-
if RAILS_GTE_5_1
|
78
|
-
# Everything works fine as it is
|
79
|
-
yield
|
80
|
-
else
|
81
|
-
# Any particular call to `changed_attributes` produces the huge memory allocation.
|
82
|
-
# Lets use the generic AR workaround for that.
|
83
|
-
@record.send(:cache_changed_attributes, &block)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
69
|
# Rails 5.1 changed the API of `ActiveRecord::Dirty`. See
|
88
70
|
# https://github.com/paper-trail-gem/paper_trail/pull/899
|
89
71
|
#
|
@@ -91,18 +73,14 @@ module PaperTrail
|
|
91
73
|
#
|
92
74
|
# @api private
|
93
75
|
def attribute_in_previous_version(attr_name, is_touch)
|
94
|
-
if
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
@record.attribute_before_last_save(attr_name.to_s)
|
99
|
-
else
|
100
|
-
# We are either performing a `record_destroy` or a
|
101
|
-
# `record_update(is_touch: true)`.
|
102
|
-
@record.attribute_in_database(attr_name.to_s)
|
103
|
-
end
|
76
|
+
if @in_after_callback && !is_touch
|
77
|
+
# For most events, we want the original value of the attribute, before
|
78
|
+
# the last save.
|
79
|
+
@record.attribute_before_last_save(attr_name.to_s)
|
104
80
|
else
|
105
|
-
|
81
|
+
# We are either performing a `record_destroy` or a
|
82
|
+
# `record_update(is_touch: true)`.
|
83
|
+
@record.attribute_in_database(attr_name.to_s)
|
106
84
|
end
|
107
85
|
end
|
108
86
|
|
@@ -138,7 +116,7 @@ module PaperTrail
|
|
138
116
|
def changes_in_latest_version
|
139
117
|
# Memoized to reduce memory usage
|
140
118
|
@changes_in_latest_version ||= begin
|
141
|
-
if @in_after_callback
|
119
|
+
if @in_after_callback
|
142
120
|
@record.saved_changes
|
143
121
|
else
|
144
122
|
@record.changes
|
@@ -263,7 +241,7 @@ module PaperTrail
|
|
263
241
|
# @api private
|
264
242
|
# @param changes HashWithIndifferentAccess
|
265
243
|
def recordable_object_changes(changes)
|
266
|
-
if PaperTrail.config.object_changes_adapter
|
244
|
+
if PaperTrail.config.object_changes_adapter.respond_to?(:diff)
|
267
245
|
# We'd like to avoid the `to_hash` here, because it increases memory
|
268
246
|
# usage, but that would be a breaking change because
|
269
247
|
# `object_changes_adapter` expects a plain `Hash`, not a
|
@@ -1,5 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
4
|
-
#
|
3
|
+
# Either ActiveRecord has already been loaded by the Lazy Load Hook in our
|
4
|
+
# Railtie, or else we load it now.
|
5
|
+
require "active_record"
|
6
|
+
::PaperTrail::Compatibility.check_activerecord(::ActiveRecord.gem_version)
|
7
|
+
|
8
|
+
# Now we can load the parts of PT that depend on AR.
|
9
|
+
require "paper_trail/has_paper_trail"
|
10
|
+
require "paper_trail/reifier"
|
5
11
|
require "paper_trail/frameworks/active_record/models/paper_trail/version"
|
12
|
+
ActiveRecord::Base.include PaperTrail::Model
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PaperTrail
|
4
|
+
# Represents code to load within Rails framework. See documentation in
|
5
|
+
# `railties/lib/rails/railtie.rb`.
|
6
|
+
# @api private
|
7
|
+
class Railtie < ::Rails::Railtie
|
8
|
+
# PaperTrail only has one initializer.
|
9
|
+
#
|
10
|
+
# We specify `before: "load_config_initializers"` to ensure that the PT
|
11
|
+
# initializer happens before "app initializers" (those defined in
|
12
|
+
# the app's `config/initalizers`).
|
13
|
+
initializer "paper_trail", before: "load_config_initializers" do
|
14
|
+
# `on_load` is a "lazy load hook". It "declares a block that will be
|
15
|
+
# executed when a Rails component is fully loaded". (See
|
16
|
+
# `active_support/lazy_load_hooks.rb`)
|
17
|
+
ActiveSupport.on_load(:action_controller) do
|
18
|
+
require "paper_trail/frameworks/rails/controller"
|
19
|
+
|
20
|
+
# Mix our extensions into `ActionController::Base`, which is `self`
|
21
|
+
# because of the `class_eval` in `lazy_load_hooks.rb`.
|
22
|
+
include PaperTrail::Rails::Controller
|
23
|
+
end
|
24
|
+
|
25
|
+
ActiveSupport.on_load(:active_record) do
|
26
|
+
require "paper_trail/frameworks/active_record"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -122,8 +122,9 @@ module PaperTrail
|
|
122
122
|
setup_callbacks_from_options options[:on]
|
123
123
|
end
|
124
124
|
|
125
|
+
# @api private
|
125
126
|
def version_class
|
126
|
-
@
|
127
|
+
@version_class ||= @model_class.version_class_name.constantize
|
127
128
|
end
|
128
129
|
|
129
130
|
private
|
@@ -23,7 +23,7 @@ module PaperTrail
|
|
23
23
|
|
24
24
|
# @api private
|
25
25
|
def execute
|
26
|
-
if PaperTrail.config.object_changes_adapter
|
26
|
+
if PaperTrail.config.object_changes_adapter.respond_to?(:where_object_changes)
|
27
27
|
return PaperTrail.config.object_changes_adapter.where_object_changes(
|
28
28
|
@version_model_class, @attributes
|
29
29
|
)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PaperTrail
|
4
|
+
module Queries
|
5
|
+
module Versions
|
6
|
+
# For public API documentation, see `where_object_changes_from` in
|
7
|
+
# `paper_trail/version_concern.rb`.
|
8
|
+
# @api private
|
9
|
+
class WhereObjectChangesFrom
|
10
|
+
# - version_model_class - The class that VersionConcern was mixed into.
|
11
|
+
# - attributes - A `Hash` of attributes and values. See the public API
|
12
|
+
# documentation for details.
|
13
|
+
# @api private
|
14
|
+
def initialize(version_model_class, attributes)
|
15
|
+
@version_model_class = version_model_class
|
16
|
+
@attributes = attributes
|
17
|
+
end
|
18
|
+
|
19
|
+
# @api private
|
20
|
+
def execute
|
21
|
+
if PaperTrail.config.object_changes_adapter.respond_to?(:where_object_changes_from)
|
22
|
+
return PaperTrail.config.object_changes_adapter.where_object_changes_from(
|
23
|
+
@version_model_class, @attributes
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
case @version_model_class.columns_hash["object_changes"].type
|
28
|
+
when :jsonb, :json
|
29
|
+
json
|
30
|
+
else
|
31
|
+
text
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# @api private
|
38
|
+
def json
|
39
|
+
predicates = []
|
40
|
+
values = []
|
41
|
+
@attributes.each do |field, value|
|
42
|
+
predicates.push(
|
43
|
+
"(object_changes->>? ILIKE ?)"
|
44
|
+
)
|
45
|
+
values.concat([field, "[#{value.to_json},%"])
|
46
|
+
end
|
47
|
+
sql = predicates.join(" and ")
|
48
|
+
@version_model_class.where(sql, *values)
|
49
|
+
end
|
50
|
+
|
51
|
+
# @api private
|
52
|
+
def text
|
53
|
+
arel_field = @version_model_class.arel_table[:object_changes]
|
54
|
+
|
55
|
+
where_conditions = @attributes.map do |field, value|
|
56
|
+
::PaperTrail.serializer.where_object_changes_from_condition(arel_field, field, value)
|
57
|
+
end
|
58
|
+
|
59
|
+
where_conditions = where_conditions.reduce { |a, e| a.and(e) }
|
60
|
+
@version_model_class.where(where_conditions)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -7,8 +7,6 @@ require "paper_trail/events/update"
|
|
7
7
|
module PaperTrail
|
8
8
|
# Represents the "paper trail" for a single record.
|
9
9
|
class RecordTrail
|
10
|
-
RAILS_GTE_5_1 = ::ActiveRecord.gem_version >= ::Gem::Version.new("5.1.0.beta1")
|
11
|
-
|
12
10
|
def initialize(record)
|
13
11
|
@record = record
|
14
12
|
end
|
@@ -200,9 +198,9 @@ module PaperTrail
|
|
200
198
|
#
|
201
199
|
# This is an "update" event. That is, we record the same data we would in
|
202
200
|
# the case of a normal AR `update`.
|
203
|
-
def save_with_version(
|
201
|
+
def save_with_version(**options)
|
204
202
|
::PaperTrail.request(enabled: false) do
|
205
|
-
@record.save(
|
203
|
+
@record.save(**options)
|
206
204
|
end
|
207
205
|
record_update(force: true, in_after_callback: false, is_touch: false)
|
208
206
|
end
|
@@ -41,6 +41,14 @@ module PaperTrail
|
|
41
41
|
discussion at https://github.com/paper-trail-gem/paper_trail/issues/803
|
42
42
|
STR
|
43
43
|
end
|
44
|
+
|
45
|
+
# Raises an exception as this operation is not allowed from text columns.
|
46
|
+
def where_object_changes_from_condition(*)
|
47
|
+
raise <<-STR.squish.freeze
|
48
|
+
where_object_changes_from does not support reading JSON from a text
|
49
|
+
column. The json and jsonb datatypes are supported.
|
50
|
+
STR
|
51
|
+
end
|
44
52
|
end
|
45
53
|
end
|
46
54
|
end
|
@@ -38,6 +38,14 @@ module PaperTrail
|
|
38
38
|
discussion at https://github.com/paper-trail-gem/paper_trail/pull/997
|
39
39
|
STR
|
40
40
|
end
|
41
|
+
|
42
|
+
# Raises an exception as this operation is not allowed with YAML.
|
43
|
+
def where_object_changes_from_condition(*)
|
44
|
+
raise <<-STR.squish.freeze
|
45
|
+
where_object_changes_from does not support reading YAML from a text
|
46
|
+
column. The json and jsonb datatypes are supported.
|
47
|
+
STR
|
48
|
+
end
|
41
49
|
end
|
42
50
|
end
|
43
51
|
end
|
@@ -11,15 +11,12 @@ module PaperTrail
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def serialize(array)
|
14
|
-
return serialize_with_ar(array) if active_record_pre_502?
|
15
14
|
array
|
16
15
|
end
|
17
16
|
|
18
17
|
def deserialize(array)
|
19
|
-
return deserialize_with_ar(array) if active_record_pre_502?
|
20
|
-
|
21
18
|
case array
|
22
|
-
# Needed for legacy
|
19
|
+
# Needed for legacy data. If serialized array is a string
|
23
20
|
# then it was serialized with Rails < 5.0.2.
|
24
21
|
when ::String then deserialize_with_ar(array)
|
25
22
|
else array
|
@@ -28,16 +25,6 @@ module PaperTrail
|
|
28
25
|
|
29
26
|
private
|
30
27
|
|
31
|
-
def active_record_pre_502?
|
32
|
-
::ActiveRecord.gem_version < Gem::Version.new("5.0.2")
|
33
|
-
end
|
34
|
-
|
35
|
-
def serialize_with_ar(array)
|
36
|
-
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array.
|
37
|
-
new(@subtype, @delimiter).
|
38
|
-
serialize(array)
|
39
|
-
end
|
40
|
-
|
41
28
|
def deserialize_with_ar(array)
|
42
29
|
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array.
|
43
30
|
new(@subtype, @delimiter).
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require "paper_trail/attribute_serializers/object_changes_attribute"
|
4
4
|
require "paper_trail/queries/versions/where_object"
|
5
5
|
require "paper_trail/queries/versions/where_object_changes"
|
6
|
+
require "paper_trail/queries/versions/where_object_changes_from"
|
6
7
|
|
7
8
|
module PaperTrail
|
8
9
|
# Originally, PaperTrail did not provide this module, and all of this
|
@@ -13,12 +14,7 @@ module PaperTrail
|
|
13
14
|
extend ::ActiveSupport::Concern
|
14
15
|
|
15
16
|
included do
|
16
|
-
|
17
|
-
belongs_to :item, polymorphic: true, optional: true
|
18
|
-
else
|
19
|
-
belongs_to :item, polymorphic: true
|
20
|
-
end
|
21
|
-
|
17
|
+
belongs_to :item, polymorphic: true, optional: true
|
22
18
|
validates_presence_of :event
|
23
19
|
after_create :enforce_version_limit!
|
24
20
|
end
|
@@ -120,6 +116,21 @@ module PaperTrail
|
|
120
116
|
Queries::Versions::WhereObjectChanges.new(self, args).execute
|
121
117
|
end
|
122
118
|
|
119
|
+
# Given a hash of attributes like `name: 'Joan'`, query the
|
120
|
+
# `versions.objects_changes` column for changes where the version changed
|
121
|
+
# from the hash of attributes to other values.
|
122
|
+
#
|
123
|
+
# This is useful for finding versions where the attribute started with a
|
124
|
+
# known value and changed to something else. This is in comparison to
|
125
|
+
# `where_object_changes` which will find both the changes before and
|
126
|
+
# after.
|
127
|
+
#
|
128
|
+
# @api public
|
129
|
+
def where_object_changes_from(args = {})
|
130
|
+
raise ArgumentError, "expected to receive a Hash" unless args.is_a?(Hash)
|
131
|
+
Queries::Versions::WhereObjectChangesFrom.new(self, args).execute
|
132
|
+
end
|
133
|
+
|
123
134
|
def primary_key_is_int?
|
124
135
|
@primary_key_is_int ||= columns_hash[primary_key].type == :integer
|
125
136
|
rescue StandardError # TODO: Rescue something more specific
|
@@ -273,7 +284,7 @@ module PaperTrail
|
|
273
284
|
|
274
285
|
# @api private
|
275
286
|
def load_changeset
|
276
|
-
if PaperTrail.config.object_changes_adapter
|
287
|
+
if PaperTrail.config.object_changes_adapter.respond_to?(:load_changeset)
|
277
288
|
return PaperTrail.config.object_changes_adapter.load_changeset(self)
|
278
289
|
end
|
279
290
|
|
@@ -7,8 +7,8 @@ module PaperTrail
|
|
7
7
|
# because of this confusion, but it's not worth the breaking change.
|
8
8
|
# People are encouraged to use `PaperTrail.gem_version` instead.
|
9
9
|
module VERSION
|
10
|
-
MAJOR =
|
11
|
-
MINOR =
|
10
|
+
MAJOR = 12
|
11
|
+
MINOR = 0
|
12
12
|
TINY = 0
|
13
13
|
|
14
14
|
# Set PRE to nil unless it's a pre-release (beta, rc, etc.)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paper_trail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 12.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Stewart
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2021-03-29 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -158,42 +158,70 @@ dependencies:
|
|
158
158
|
requirements:
|
159
159
|
- - "~>"
|
160
160
|
- !ruby/object:Gem::Version
|
161
|
-
version:
|
161
|
+
version: 1.11.0
|
162
162
|
type: :development
|
163
163
|
prerelease: false
|
164
164
|
version_requirements: !ruby/object:Gem::Requirement
|
165
165
|
requirements:
|
166
166
|
- - "~>"
|
167
167
|
- !ruby/object:Gem::Version
|
168
|
-
version:
|
168
|
+
version: 1.11.0
|
169
|
+
- !ruby/object:Gem::Dependency
|
170
|
+
name: rubocop-rails
|
171
|
+
requirement: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - "~>"
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: 2.9.1
|
176
|
+
type: :development
|
177
|
+
prerelease: false
|
178
|
+
version_requirements: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - "~>"
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: 2.9.1
|
183
|
+
- !ruby/object:Gem::Dependency
|
184
|
+
name: rubocop-packaging
|
185
|
+
requirement: !ruby/object:Gem::Requirement
|
186
|
+
requirements:
|
187
|
+
- - "~>"
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: 0.5.1
|
190
|
+
type: :development
|
191
|
+
prerelease: false
|
192
|
+
version_requirements: !ruby/object:Gem::Requirement
|
193
|
+
requirements:
|
194
|
+
- - "~>"
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: 0.5.1
|
169
197
|
- !ruby/object:Gem::Dependency
|
170
198
|
name: rubocop-performance
|
171
199
|
requirement: !ruby/object:Gem::Requirement
|
172
200
|
requirements:
|
173
201
|
- - "~>"
|
174
202
|
- !ruby/object:Gem::Version
|
175
|
-
version: 1.
|
203
|
+
version: 1.10.1
|
176
204
|
type: :development
|
177
205
|
prerelease: false
|
178
206
|
version_requirements: !ruby/object:Gem::Requirement
|
179
207
|
requirements:
|
180
208
|
- - "~>"
|
181
209
|
- !ruby/object:Gem::Version
|
182
|
-
version: 1.
|
210
|
+
version: 1.10.1
|
183
211
|
- !ruby/object:Gem::Dependency
|
184
212
|
name: rubocop-rspec
|
185
213
|
requirement: !ruby/object:Gem::Requirement
|
186
214
|
requirements:
|
187
215
|
- - "~>"
|
188
216
|
- !ruby/object:Gem::Version
|
189
|
-
version:
|
217
|
+
version: 2.2.0
|
190
218
|
type: :development
|
191
219
|
prerelease: false
|
192
220
|
version_requirements: !ruby/object:Gem::Requirement
|
193
221
|
requirements:
|
194
222
|
- - "~>"
|
195
223
|
- !ruby/object:Gem::Version
|
196
|
-
version:
|
224
|
+
version: 2.2.0
|
197
225
|
- !ruby/object:Gem::Dependency
|
198
226
|
name: mysql2
|
199
227
|
requirement: !ruby/object:Gem::Requirement
|
@@ -251,7 +279,6 @@ executables: []
|
|
251
279
|
extensions: []
|
252
280
|
extra_rdoc_files: []
|
253
281
|
files:
|
254
|
-
- Gemfile
|
255
282
|
- LICENSE
|
256
283
|
- lib/generators/paper_trail/install/USAGE
|
257
284
|
- lib/generators/paper_trail/install/install_generator.rb
|
@@ -279,13 +306,14 @@ files:
|
|
279
306
|
- lib/paper_trail/frameworks/cucumber.rb
|
280
307
|
- lib/paper_trail/frameworks/rails.rb
|
281
308
|
- lib/paper_trail/frameworks/rails/controller.rb
|
282
|
-
- lib/paper_trail/frameworks/rails/
|
309
|
+
- lib/paper_trail/frameworks/rails/railtie.rb
|
283
310
|
- lib/paper_trail/frameworks/rspec.rb
|
284
311
|
- lib/paper_trail/frameworks/rspec/helpers.rb
|
285
312
|
- lib/paper_trail/has_paper_trail.rb
|
286
313
|
- lib/paper_trail/model_config.rb
|
287
314
|
- lib/paper_trail/queries/versions/where_object.rb
|
288
315
|
- lib/paper_trail/queries/versions/where_object_changes.rb
|
316
|
+
- lib/paper_trail/queries/versions/where_object_changes_from.rb
|
289
317
|
- lib/paper_trail/record_history.rb
|
290
318
|
- lib/paper_trail/record_trail.rb
|
291
319
|
- lib/paper_trail/reifier.rb
|
@@ -295,7 +323,6 @@ files:
|
|
295
323
|
- lib/paper_trail/type_serializers/postgres_array_serializer.rb
|
296
324
|
- lib/paper_trail/version_concern.rb
|
297
325
|
- lib/paper_trail/version_number.rb
|
298
|
-
- paper_trail.gemspec
|
299
326
|
homepage: https://github.com/paper-trail-gem/paper_trail
|
300
327
|
licenses:
|
301
328
|
- MIT
|
@@ -308,14 +335,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
308
335
|
requirements:
|
309
336
|
- - ">="
|
310
337
|
- !ruby/object:Gem::Version
|
311
|
-
version: 2.
|
338
|
+
version: 2.5.0
|
312
339
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
313
340
|
requirements:
|
314
341
|
- - ">="
|
315
342
|
- !ruby/object:Gem::Version
|
316
343
|
version: 1.3.6
|
317
344
|
requirements: []
|
318
|
-
|
345
|
+
rubyforge_project:
|
346
|
+
rubygems_version: 2.7.6.2
|
319
347
|
signing_key:
|
320
348
|
specification_version: 4
|
321
349
|
summary: Track changes to your models.
|
data/Gemfile
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module PaperTrail
|
4
|
-
module Rails
|
5
|
-
# See http://guides.rubyonrails.org/engines.html
|
6
|
-
class Engine < ::Rails::Engine
|
7
|
-
DPR_CONFIG_ENABLED = <<~EOS.squish.freeze
|
8
|
-
The rails configuration option config.paper_trail.enabled is deprecated.
|
9
|
-
Please use PaperTrail.enabled= instead. People were getting confused
|
10
|
-
that PT has both, specifically regarding *when* each was happening. If
|
11
|
-
you'd like to keep config.paper_trail, join the discussion at
|
12
|
-
https://github.com/paper-trail-gem/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
|
-
|
26
|
-
paths["app/models"] << "lib/paper_trail/frameworks/active_record/models"
|
27
|
-
|
28
|
-
# --- Begin deprecated section ---
|
29
|
-
config.paper_trail = ActiveSupport::OrderedOptions.new
|
30
|
-
initializer "paper_trail.initialisation" do |app|
|
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
|
41
|
-
end
|
42
|
-
# --- End deprecated section ---
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
data/paper_trail.gemspec
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
$LOAD_PATH.unshift File.expand_path("lib", __dir__)
|
4
|
-
require "paper_trail/compatibility"
|
5
|
-
require "paper_trail/version_number"
|
6
|
-
|
7
|
-
Gem::Specification.new do |s|
|
8
|
-
s.name = "paper_trail"
|
9
|
-
s.version = PaperTrail::VERSION::STRING
|
10
|
-
s.platform = Gem::Platform::RUBY
|
11
|
-
s.summary = "Track changes to your models."
|
12
|
-
s.description = <<-EOS
|
13
|
-
Track changes to your models, for auditing or versioning. See how a model looked
|
14
|
-
at any stage in its lifecycle, revert it to any version, or restore it after it
|
15
|
-
has been destroyed.
|
16
|
-
EOS
|
17
|
-
s.homepage = "https://github.com/paper-trail-gem/paper_trail"
|
18
|
-
s.authors = ["Andy Stewart", "Ben Atkins", "Jared Beck"]
|
19
|
-
s.email = "jared@jaredbeck.com"
|
20
|
-
s.license = "MIT"
|
21
|
-
|
22
|
-
s.files = `git ls-files -z`.split("\x0").select { |f|
|
23
|
-
f.match(%r{^(Gemfile|LICENSE|lib/|paper_trail.gemspec)})
|
24
|
-
}
|
25
|
-
s.executables = []
|
26
|
-
s.require_paths = ["lib"]
|
27
|
-
|
28
|
-
s.required_rubygems_version = ">= 1.3.6"
|
29
|
-
|
30
|
-
# Ruby 2.4 reaches EoL at the end of March of 2020
|
31
|
-
# https://www.ruby-lang.org/en/news/2019/10/02/ruby-2-4-9-released/
|
32
|
-
s.required_ruby_version = ">= 2.4.0"
|
33
|
-
|
34
|
-
# We no longer specify a maximum activerecord version.
|
35
|
-
# See discussion in paper_trail/compatibility.rb
|
36
|
-
s.add_dependency "activerecord", ::PaperTrail::Compatibility::ACTIVERECORD_GTE
|
37
|
-
s.add_dependency "request_store", "~> 1.1"
|
38
|
-
|
39
|
-
s.add_development_dependency "appraisal", "~> 2.2"
|
40
|
-
s.add_development_dependency "byebug", "~> 11.0"
|
41
|
-
s.add_development_dependency "ffaker", "~> 2.11"
|
42
|
-
s.add_development_dependency "generator_spec", "~> 0.9.4"
|
43
|
-
s.add_development_dependency "memory_profiler", "~> 0.9.14"
|
44
|
-
|
45
|
-
# For `spec/dummy_app`. Technically, we only need `actionpack` (as of 2020).
|
46
|
-
# However, that might change in the future, and the advantages of specifying a
|
47
|
-
# subset (e.g. actionpack only) are unclear.
|
48
|
-
s.add_development_dependency "rails", ::PaperTrail::Compatibility::ACTIVERECORD_GTE
|
49
|
-
|
50
|
-
s.add_development_dependency "rake", "~> 13.0"
|
51
|
-
s.add_development_dependency "rspec-rails", "~> 4.0"
|
52
|
-
s.add_development_dependency "rubocop", "~> 0.89.1"
|
53
|
-
s.add_development_dependency "rubocop-performance", "~> 1.7.1"
|
54
|
-
s.add_development_dependency "rubocop-rspec", "~> 1.42.0"
|
55
|
-
|
56
|
-
# ## Database Adapters
|
57
|
-
#
|
58
|
-
# The dependencies here must match the `gem` call at the top of their
|
59
|
-
# adapters, eg. `active_record/connection_adapters/mysql2_adapter.rb`,
|
60
|
-
# assuming said call is consistent for all versions of rails we test against
|
61
|
-
# (see `Appraisals`).
|
62
|
-
#
|
63
|
-
# Currently, all versions of rails we test against are consistent. In the past,
|
64
|
-
# when we tested against rails 4.2, we had to specify database adapters in
|
65
|
-
# `Appraisals`.
|
66
|
-
s.add_development_dependency "mysql2", "~> 0.5"
|
67
|
-
s.add_development_dependency "pg", ">= 0.18", "< 2.0"
|
68
|
-
s.add_development_dependency "sqlite3", "~> 1.4"
|
69
|
-
end
|