paper_trail 16.0.0 → 17.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/lib/generators/paper_trail/install/USAGE +29 -1
- data/lib/generators/paper_trail/install/install_generator.rb +6 -4
- data/lib/generators/paper_trail/install/templates/add_object_changes_to_versions.rb.erb +2 -2
- data/lib/generators/paper_trail/install/templates/create_versions.rb.erb +4 -4
- data/lib/generators/paper_trail/migration_generator.rb +29 -2
- data/lib/generators/paper_trail/update_item_subtype/templates/update_versions_for_item_subtype.rb.erb +7 -6
- data/lib/generators/paper_trail/update_item_subtype/update_item_subtype_generator.rb +23 -2
- data/lib/paper_trail/attribute_serializers/cast_attribute_serializer.rb +1 -1
- data/lib/paper_trail/attribute_serializers/object_attribute.rb +1 -4
- data/lib/paper_trail/attribute_serializers/object_changes_attribute.rb +1 -4
- data/lib/paper_trail/compatibility.rb +2 -2
- data/lib/paper_trail/events/base.rb +1 -1
- data/lib/paper_trail/frameworks/active_record.rb +1 -1
- data/lib/paper_trail/frameworks/cucumber.rb +1 -1
- data/lib/paper_trail/frameworks/rspec.rb +8 -8
- data/lib/paper_trail/model_config.rb +3 -3
- data/lib/paper_trail/queries/versions/where_object.rb +1 -1
- data/lib/paper_trail/queries/versions/where_object_changes.rb +1 -1
- data/lib/paper_trail/queries/versions/where_object_changes_from.rb +1 -1
- data/lib/paper_trail/queries/versions/where_object_changes_to.rb +1 -1
- data/lib/paper_trail/record_trail.rb +3 -3
- data/lib/paper_trail/reifier.rb +3 -3
- data/lib/paper_trail/serializers/yaml.rb +1 -1
- data/lib/paper_trail/version_concern.rb +1 -1
- data/lib/paper_trail/version_number.rb +1 -1
- data/lib/paper_trail.rb +0 -4
- metadata +107 -25
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce4b87054886d17b9dea51dfcf6e9ddc948eaf331417b8dc5b992793e177a670
|
|
4
|
+
data.tar.gz: 32f2ff0f24978fe54e08a65dfe8c83ec023eaaf9ab676c0f791b398907a8fc80
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 772518531867cafb80017ebbb42837412fc67b80ec9416cfc9269595084e266f312609115171868b4124747769f1aba03fd5ee1b932691b52128aaec6fa2c583
|
|
7
|
+
data.tar.gz: 3b28ed9bbbf1fef2eac6d106c5fedcb1566b88d7877782e115130f4f8386f5e6bf60f4123edc1518e41478b918fac9c371c98fea5e0b49745fcd384cffa85baa
|
|
@@ -1,3 +1,31 @@
|
|
|
1
1
|
Description:
|
|
2
2
|
Generates (but does not run) a migration to add a versions table. Also generates an initializer
|
|
3
|
-
file for configuring PaperTrail.
|
|
3
|
+
file for configuring PaperTrail. Can be customized by providing a Version class name.
|
|
4
|
+
See section 5.c. Generators in README.md for more information.
|
|
5
|
+
|
|
6
|
+
Examples:
|
|
7
|
+
rails generate paper_trail:install
|
|
8
|
+
|
|
9
|
+
This will create:
|
|
10
|
+
db/migrate/[TIMESTAMP]_create_versions.rb
|
|
11
|
+
config/initializers/paper_trail.rb
|
|
12
|
+
|
|
13
|
+
rails generate paper_trail:install --with-changes
|
|
14
|
+
|
|
15
|
+
This will create:
|
|
16
|
+
db/migrate/[TIMESTAMP]_create_versions.rb
|
|
17
|
+
db/migrate/[TIMESTAMP]_add_object_changes_to_versions.rb
|
|
18
|
+
config/initializers/paper_trail.rb
|
|
19
|
+
|
|
20
|
+
rails generate paper_trail:install CommentVersion
|
|
21
|
+
|
|
22
|
+
This will create:
|
|
23
|
+
db/migrate/[TIMESTAMP]_create_comment_versions.rb
|
|
24
|
+
config/initializers/paper_trail.rb
|
|
25
|
+
|
|
26
|
+
rails generate paper_trail:install ProductVersion --with-changes --uuid
|
|
27
|
+
|
|
28
|
+
This will create:
|
|
29
|
+
db/migrate/[TIMESTAMP]_create_product_versions.rb
|
|
30
|
+
db/migrate/[TIMESTAMP]_add_object_changes_to_product_versions.rb
|
|
31
|
+
config/initializers/paper_trail.rb
|
|
@@ -27,19 +27,21 @@ module PaperTrail
|
|
|
27
27
|
desc: "Use uuid instead of bigint for item_id type (use only if tables use UUIDs)"
|
|
28
28
|
)
|
|
29
29
|
|
|
30
|
-
desc "Generates (but does not run) a migration to add a versions table." \
|
|
31
|
-
"
|
|
30
|
+
desc "Generates (but does not run) a migration to add a versions table. " \
|
|
31
|
+
"Can be customized by providing a Version class name. " \
|
|
32
|
+
"See section 5.c. Generators in README.md for more information."
|
|
32
33
|
|
|
33
34
|
def create_migration_file
|
|
35
|
+
# Use the table_name to create the proper migration filename
|
|
34
36
|
add_paper_trail_migration(
|
|
35
|
-
"
|
|
37
|
+
"create_#{table_name}",
|
|
36
38
|
item_type_options: item_type_options,
|
|
37
39
|
versions_table_options: versions_table_options,
|
|
38
40
|
item_id_type_options: item_id_type_options,
|
|
39
41
|
version_table_primary_key_type: version_table_primary_key_type
|
|
40
42
|
)
|
|
41
43
|
if options.with_changes?
|
|
42
|
-
add_paper_trail_migration("
|
|
44
|
+
add_paper_trail_migration("add_object_changes_to_#{table_name}")
|
|
43
45
|
end
|
|
44
46
|
end
|
|
45
47
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# This migration adds the optional `object_changes` column, in which PaperTrail
|
|
2
2
|
# will store the `changes` diff for each update event. See the readme for
|
|
3
3
|
# details.
|
|
4
|
-
class
|
|
4
|
+
class AddObjectChangesTo<%= version_class_name.pluralize %> < ActiveRecord::Migration<%= migration_version %>
|
|
5
5
|
# The largest text column available in all supported RDBMS.
|
|
6
6
|
# See `create_versions.rb` for details.
|
|
7
7
|
TEXT_BYTES = 1_073_741_823
|
|
8
8
|
|
|
9
9
|
def change
|
|
10
|
-
add_column
|
|
10
|
+
add_column :<%= table_name %>, :object_changes, :text, limit: TEXT_BYTES
|
|
11
11
|
end
|
|
12
12
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# This migration creates the
|
|
1
|
+
# This migration creates the `<%= table_name %>` table for the <%= version_class_name %> class.
|
|
2
2
|
# All other migrations PT provides are optional.
|
|
3
|
-
class
|
|
3
|
+
class Create<%= version_class_name.pluralize %> < ActiveRecord::Migration<%= migration_version %>
|
|
4
4
|
|
|
5
5
|
# The largest text column available in all supported RDBMS is
|
|
6
6
|
# 1024^3 - 1 bytes, roughly one gibibyte. We specify a size
|
|
@@ -9,7 +9,7 @@ class CreateVersions < ActiveRecord::Migration<%= migration_version %>
|
|
|
9
9
|
TEXT_BYTES = 1_073_741_823
|
|
10
10
|
|
|
11
11
|
def change
|
|
12
|
-
create_table
|
|
12
|
+
create_table :<%= table_name %><%= versions_table_options %><%= version_table_primary_key_type %> do |t|
|
|
13
13
|
# Consider using bigint type for performance if you are going to store only numeric ids.
|
|
14
14
|
# t.bigint :whodunnit
|
|
15
15
|
t.string :whodunnit
|
|
@@ -36,6 +36,6 @@ class CreateVersions < ActiveRecord::Migration<%= migration_version %>
|
|
|
36
36
|
t.string :event, null: false
|
|
37
37
|
t.text :object, limit: TEXT_BYTES
|
|
38
38
|
end
|
|
39
|
-
add_index
|
|
39
|
+
add_index :<%= table_name %>, %i[item_type item_id]
|
|
40
40
|
end
|
|
41
41
|
end
|
|
@@ -8,6 +8,10 @@ module PaperTrail
|
|
|
8
8
|
class MigrationGenerator < ::Rails::Generators::Base
|
|
9
9
|
include ::Rails::Generators::Migration
|
|
10
10
|
|
|
11
|
+
# Define arguments for the generator
|
|
12
|
+
argument :version_class_name, type: :string, default: "Version",
|
|
13
|
+
desc: "The name of the Version class (e.g., CommentVersion)"
|
|
14
|
+
|
|
11
15
|
def self.next_migration_number(dirname)
|
|
12
16
|
::ActiveRecord::Generators::Base.next_migration_number(dirname)
|
|
13
17
|
end
|
|
@@ -19,10 +23,17 @@ module PaperTrail
|
|
|
19
23
|
if self.class.migration_exists?(migration_dir, template)
|
|
20
24
|
::Kernel.warn "Migration already exists: #{template}"
|
|
21
25
|
else
|
|
26
|
+
# Map the dynamic template name to the actual template file
|
|
27
|
+
template_file = map_template_name(template)
|
|
28
|
+
|
|
22
29
|
migration_template(
|
|
23
|
-
"#{
|
|
30
|
+
"#{template_file}.rb.erb",
|
|
24
31
|
"db/migrate/#{template}.rb",
|
|
25
|
-
{
|
|
32
|
+
{
|
|
33
|
+
migration_version: migration_version,
|
|
34
|
+
table_name: table_name,
|
|
35
|
+
version_class_name: version_class_name
|
|
36
|
+
}.merge(extra_options)
|
|
26
37
|
)
|
|
27
38
|
end
|
|
28
39
|
end
|
|
@@ -34,5 +45,21 @@ module PaperTrail
|
|
|
34
45
|
ActiveRecord::VERSION::MINOR
|
|
35
46
|
)
|
|
36
47
|
end
|
|
48
|
+
|
|
49
|
+
# Convert Version class name to table name using Rails conventions
|
|
50
|
+
def table_name
|
|
51
|
+
version_class_name.underscore.pluralize
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Map the dynamic template name to the actual template file
|
|
55
|
+
def map_template_name(template)
|
|
56
|
+
if template.start_with?("create_")
|
|
57
|
+
"create_versions"
|
|
58
|
+
elsif template.start_with?("add_object_changes_to_")
|
|
59
|
+
"add_object_changes_to_versions"
|
|
60
|
+
else
|
|
61
|
+
template
|
|
62
|
+
end
|
|
63
|
+
end
|
|
37
64
|
end
|
|
38
65
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# This migration updates existing `versions` that have `item_type` that refers to
|
|
2
2
|
# the base_class, and changes them to refer to the subclass instead.
|
|
3
|
-
class
|
|
3
|
+
class Update<%= version_class_name.pluralize %>ForItemSubtype < ActiveRecord::Migration<%= migration_version %>
|
|
4
4
|
include ActionView::Helpers::TextHelper
|
|
5
5
|
def up
|
|
6
6
|
<%=
|
|
@@ -18,7 +18,8 @@ class UpdateVersionsForItemSubtype < ActiveRecord::Migration<%= migration_versio
|
|
|
18
18
|
# # Versions of item_type "Plant" with IDs between 42 and 1337 will be updated based on `genus`
|
|
19
19
|
# hints = {"Animal"=>{1..4=>"species"}, "Plant"=>{42..1337=>"genus"}}
|
|
20
20
|
hint_descriptions = ""
|
|
21
|
-
hints
|
|
21
|
+
# Use @hints over args to not break the test itself since args could now include --version_class_name=CommentVersion
|
|
22
|
+
hints = (@hints || []).inject(Hash.new{|h, k| h[k] = {}}) do |s, v|
|
|
22
23
|
klass, column, range = parse_custom_entry(v)
|
|
23
24
|
hint_descriptions << " # Versions of item_type \"#{klass}\" with IDs between #{
|
|
24
25
|
range.first} and #{range.last} will be updated based on \`#{column}\`\n"
|
|
@@ -32,7 +33,7 @@ class UpdateVersionsForItemSubtype < ActiveRecord::Migration<%= migration_versio
|
|
|
32
33
|
%>
|
|
33
34
|
# Find all ActiveRecord models mentioned in existing versions
|
|
34
35
|
changes = Hash.new { |h, k| h[k] = [] }
|
|
35
|
-
model_names =
|
|
36
|
+
model_names = <%= fully_qualified_version_class_name %>.select(:item_type).distinct
|
|
36
37
|
model_names.map(&:item_type).each do |model_name|
|
|
37
38
|
hint = hints[model_name] if defined?(hints)
|
|
38
39
|
begin
|
|
@@ -40,7 +41,7 @@ class UpdateVersionsForItemSubtype < ActiveRecord::Migration<%= migration_versio
|
|
|
40
41
|
# Actually implements an inheritance_column? (Usually "type")
|
|
41
42
|
has_inheritance_column = klass.columns.map(&:name).include?(klass.inheritance_column)
|
|
42
43
|
# Find domain of types stored in PaperTrail versions
|
|
43
|
-
|
|
44
|
+
<%= fully_qualified_version_class_name %>.where(item_type: model_name, item_subtype: nil).select(:id, :object, :object_changes).each do |obj|
|
|
44
45
|
if (object_detail = PaperTrail.serializer.load(obj.object || obj.object_changes))
|
|
45
46
|
is_found = false
|
|
46
47
|
subtype_name = nil
|
|
@@ -72,11 +73,11 @@ class UpdateVersionsForItemSubtype < ActiveRecord::Migration<%= migration_versio
|
|
|
72
73
|
v.sort.each do |id|
|
|
73
74
|
block_of_ids << id
|
|
74
75
|
if (id_count += 1) % 100 == 0
|
|
75
|
-
num_updated +=
|
|
76
|
+
num_updated += <%= fully_qualified_version_class_name %>.where(id: block_of_ids).update_all(item_subtype: k)
|
|
76
77
|
block_of_ids = []
|
|
77
78
|
end
|
|
78
79
|
end
|
|
79
|
-
num_updated +=
|
|
80
|
+
num_updated += <%= fully_qualified_version_class_name %>.where(id: block_of_ids).update_all(item_subtype: k)
|
|
80
81
|
if num_updated > 0
|
|
81
82
|
say "Associated #{pluralize(num_updated, 'record')} to #{k}", subitem: true
|
|
82
83
|
end
|
|
@@ -7,13 +7,34 @@ module PaperTrail
|
|
|
7
7
|
class UpdateItemSubtypeGenerator < MigrationGenerator
|
|
8
8
|
source_root File.expand_path("templates", __dir__)
|
|
9
9
|
|
|
10
|
+
# Remove the inherited version_class_name argument as we use an option instead
|
|
11
|
+
remove_argument :version_class_name
|
|
12
|
+
|
|
13
|
+
argument :hints, type: :array, default: [], banner: "hint1 hint2"
|
|
14
|
+
|
|
15
|
+
class_option :version_class_name,
|
|
16
|
+
type: :string,
|
|
17
|
+
default: "Version",
|
|
18
|
+
aliases: ["-v"],
|
|
19
|
+
desc: "The name of the Version class (e.g., CommentVersion)"
|
|
20
|
+
|
|
10
21
|
desc(
|
|
11
|
-
"Generates (but does not run) a migration to update item_subtype for "\
|
|
22
|
+
"Generates (but does not run) a migration to update item_subtype for " \
|
|
12
23
|
"STI entries in an existing versions table."
|
|
13
24
|
)
|
|
14
25
|
|
|
15
26
|
def create_migration_file
|
|
16
|
-
add_paper_trail_migration("
|
|
27
|
+
add_paper_trail_migration("update_#{table_name}_for_item_subtype", sti_type_options: options)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Return the version class name from options
|
|
31
|
+
def version_class_name
|
|
32
|
+
options[:version_class_name]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Return the fully qualified class name for use in ERB templates
|
|
36
|
+
def fully_qualified_version_class_name
|
|
37
|
+
version_class_name == "Version" ? "PaperTrail::Version" : version_class_name
|
|
17
38
|
end
|
|
18
39
|
end
|
|
19
40
|
end
|
|
@@ -32,7 +32,7 @@ module PaperTrail
|
|
|
32
32
|
if defined_enums[attr] && val.is_a?(::String)
|
|
33
33
|
# Because PT 4 used to save the string version of enums to `object_changes`
|
|
34
34
|
val
|
|
35
|
-
elsif
|
|
35
|
+
elsif val.is_a?(ActiveRecord::Type::Time::Value)
|
|
36
36
|
# Because Rails 7 time attribute throws a delegation error when you deserialize
|
|
37
37
|
# it with the factory.
|
|
38
38
|
# See ActiveRecord::Type::Time::Value crashes when loaded from YAML on rails 7.0
|
|
@@ -10,10 +10,7 @@ module PaperTrail
|
|
|
10
10
|
@model_class = model_class
|
|
11
11
|
|
|
12
12
|
# ActiveRecord since 7.0 has a built-in encryption mechanism
|
|
13
|
-
@encrypted_attributes =
|
|
14
|
-
if PaperTrail.active_record_gte_7_0?
|
|
15
|
-
@model_class.encrypted_attributes&.map(&:to_s)
|
|
16
|
-
end
|
|
13
|
+
@encrypted_attributes = @model_class.encrypted_attributes&.map(&:to_s)
|
|
17
14
|
end
|
|
18
15
|
|
|
19
16
|
def serialize(attributes)
|
|
@@ -10,10 +10,7 @@ module PaperTrail
|
|
|
10
10
|
@item_class = item_class
|
|
11
11
|
|
|
12
12
|
# ActiveRecord since 7.0 has a built-in encryption mechanism
|
|
13
|
-
@encrypted_attributes =
|
|
14
|
-
if PaperTrail.active_record_gte_7_0?
|
|
15
|
-
@item_class.encrypted_attributes&.map(&:to_s)
|
|
16
|
-
end
|
|
13
|
+
@encrypted_attributes = @item_class.encrypted_attributes&.map(&:to_s)
|
|
17
14
|
end
|
|
18
15
|
|
|
19
16
|
def serialize(changes)
|
|
@@ -17,8 +17,8 @@ module PaperTrail
|
|
|
17
17
|
# newer rails versions. Most PT users should avoid incompatible rails
|
|
18
18
|
# versions.
|
|
19
19
|
module Compatibility
|
|
20
|
-
ACTIVERECORD_GTE = ">=
|
|
21
|
-
ACTIVERECORD_LT = "< 8.
|
|
20
|
+
ACTIVERECORD_GTE = ">= 7.1" # enforced in gemspec
|
|
21
|
+
ACTIVERECORD_LT = "< 8.2" # not enforced in gemspec
|
|
22
22
|
|
|
23
23
|
E_INCOMPATIBLE_AR = <<-EOS
|
|
24
24
|
PaperTrail %s is not compatible with ActiveRecord %s. We allow PT
|
|
@@ -157,7 +157,7 @@ module PaperTrail
|
|
|
157
157
|
# @api private
|
|
158
158
|
def ignored_attr_has_changed?
|
|
159
159
|
ignored = calculated_ignored_array + @record.paper_trail_options[:skip]
|
|
160
|
-
ignored.any? && (
|
|
160
|
+
ignored.any? && changed_in_latest_version.intersect?(ignored)
|
|
161
161
|
end
|
|
162
162
|
|
|
163
163
|
# Rails 5.1 changed the API of `ActiveRecord::Dirty`. See
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# Either ActiveRecord has already been loaded by the Lazy Load Hook in our
|
|
4
4
|
# Railtie, or else we load it now.
|
|
5
5
|
require "active_record"
|
|
6
|
-
|
|
6
|
+
PaperTrail::Compatibility.check_activerecord(ActiveRecord.gem_version)
|
|
7
7
|
|
|
8
8
|
# Now we can load the parts of PT that depend on AR.
|
|
9
9
|
require "paper_trail/has_paper_trail"
|
|
@@ -5,24 +5,24 @@ require "rspec/matchers"
|
|
|
5
5
|
require "paper_trail/frameworks/rspec/helpers"
|
|
6
6
|
|
|
7
7
|
RSpec.configure do |config|
|
|
8
|
-
config.include
|
|
9
|
-
config.extend
|
|
8
|
+
config.include PaperTrail::RSpec::Helpers::InstanceMethods
|
|
9
|
+
config.extend PaperTrail::RSpec::Helpers::ClassMethods
|
|
10
10
|
|
|
11
11
|
config.before(:each) do
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
PaperTrail.enabled = false
|
|
13
|
+
PaperTrail.request.enabled = true
|
|
14
|
+
PaperTrail.request.whodunnit = nil
|
|
15
|
+
PaperTrail.request.controller_info = {} if defined?(Rails) && defined?(RSpec::Rails)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
config.before(:each, versioning: true) do
|
|
19
|
-
|
|
19
|
+
PaperTrail.enabled = true
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
RSpec::Matchers.define :be_versioned do
|
|
24
24
|
# check to see if the model has `has_paper_trail` declared on it
|
|
25
|
-
match { |actual| actual.is_a?(
|
|
25
|
+
match { |actual| actual.is_a?(PaperTrail::Model::InstanceMethods) }
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
RSpec::Matchers.define :have_a_version_with do |attributes|
|
|
@@ -4,7 +4,7 @@ module PaperTrail
|
|
|
4
4
|
# Configures an ActiveRecord model, mostly at application boot time, but also
|
|
5
5
|
# sometimes mid-request, with methods like enable/disable.
|
|
6
6
|
class ModelConfig
|
|
7
|
-
E_CANNOT_RECORD_AFTER_DESTROY =
|
|
7
|
+
E_CANNOT_RECORD_AFTER_DESTROY = <<~STR
|
|
8
8
|
paper_trail.on_destroy(:after) is incompatible with ActiveRecord's
|
|
9
9
|
belongs_to_required_by_default. Use on_destroy(:before)
|
|
10
10
|
or disable belongs_to_required_by_default.
|
|
@@ -49,7 +49,7 @@ module PaperTrail
|
|
|
49
49
|
def on_destroy(recording_order = "before")
|
|
50
50
|
assert_valid_recording_order_for_on_destroy(recording_order)
|
|
51
51
|
@model_class.send(
|
|
52
|
-
"#{recording_order}_destroy",
|
|
52
|
+
:"#{recording_order}_destroy",
|
|
53
53
|
lambda do |r|
|
|
54
54
|
return unless r.paper_trail.save_version?
|
|
55
55
|
r.paper_trail.record_destroy(recording_order)
|
|
@@ -236,7 +236,7 @@ module PaperTrail
|
|
|
236
236
|
|
|
237
237
|
def setup_callbacks_from_options(options_on = [])
|
|
238
238
|
options_on.each do |event|
|
|
239
|
-
public_send("on_#{event}")
|
|
239
|
+
public_send(:"on_#{event}")
|
|
240
240
|
end
|
|
241
241
|
end
|
|
242
242
|
|
|
@@ -39,7 +39,7 @@ module PaperTrail
|
|
|
39
39
|
values = []
|
|
40
40
|
@attributes.each do |field, value|
|
|
41
41
|
predicates.push "object->>? = ?"
|
|
42
|
-
values.
|
|
42
|
+
values.push(field, value.to_s)
|
|
43
43
|
end
|
|
44
44
|
sql = predicates.join(" and ")
|
|
45
45
|
@version_model_class.where(sql, *values)
|
|
@@ -53,7 +53,7 @@ module PaperTrail
|
|
|
53
53
|
predicates.push(
|
|
54
54
|
"((object_changes->>? ILIKE ?) OR (object_changes->>? ILIKE ?))"
|
|
55
55
|
)
|
|
56
|
-
values.
|
|
56
|
+
values.push(field, "[#{value.to_json},%", field, "[%,#{value.to_json}]%")
|
|
57
57
|
end
|
|
58
58
|
sql = predicates.join(" and ")
|
|
59
59
|
@version_model_class.where(sql, *values)
|
|
@@ -22,7 +22,7 @@ module PaperTrail
|
|
|
22
22
|
# Invoked via`after_update` callback for when a previous version is
|
|
23
23
|
# reified and then saved.
|
|
24
24
|
def clear_version_instance
|
|
25
|
-
@record.send("#{@record.class.version_association_name}=", nil)
|
|
25
|
+
@record.send(:"#{@record.class.version_association_name}=", nil)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
# Returns true if this instance is the current, live one;
|
|
@@ -128,7 +128,7 @@ module PaperTrail
|
|
|
128
128
|
def reset_timestamp_attrs_for_update_if_needed
|
|
129
129
|
return if live?
|
|
130
130
|
@record.send(:timestamp_attributes_for_update_in_model).each do |column|
|
|
131
|
-
@record.send("restore_#{column}!")
|
|
131
|
+
@record.send(:"restore_#{column}!")
|
|
132
132
|
end
|
|
133
133
|
end
|
|
134
134
|
|
|
@@ -202,7 +202,7 @@ module PaperTrail
|
|
|
202
202
|
|
|
203
203
|
# @api private
|
|
204
204
|
def assign_and_reset_version_association(version)
|
|
205
|
-
@record.send("#{@record.class.version_association_name}=", version)
|
|
205
|
+
@record.send(:"#{@record.class.version_association_name}=", version)
|
|
206
206
|
@record.send(@record.class.versions_association_name).reset
|
|
207
207
|
end
|
|
208
208
|
|
data/lib/paper_trail/reifier.rb
CHANGED
|
@@ -14,7 +14,7 @@ module PaperTrail
|
|
|
14
14
|
attrs = version.object_deserialized
|
|
15
15
|
model = init_model(attrs, options, version)
|
|
16
16
|
reify_attributes(model, version, attrs)
|
|
17
|
-
model.send "#{model.class.version_association_name}=", version
|
|
17
|
+
model.send :"#{model.class.version_association_name}=", version
|
|
18
18
|
model
|
|
19
19
|
end
|
|
20
20
|
|
|
@@ -93,8 +93,8 @@ module PaperTrail
|
|
|
93
93
|
def reify_attribute(k, v, model, version)
|
|
94
94
|
if model.has_attribute?(k)
|
|
95
95
|
model[k.to_sym] = v
|
|
96
|
-
elsif model.respond_to?("#{k}=")
|
|
97
|
-
model.send("#{k}=", v)
|
|
96
|
+
elsif model.respond_to?(:"#{k}=")
|
|
97
|
+
model.send(:"#{k}=", v)
|
|
98
98
|
elsif version.logger
|
|
99
99
|
version.logger.warn(
|
|
100
100
|
"Attribute #{k} does not exist on #{version.item_type} (Version id: #{version.id})."
|
|
@@ -27,7 +27,7 @@ module PaperTrail
|
|
|
27
27
|
# recent [memory optimizations](https://github.com/paper-trail-gem/paper_trail/pull/1189),
|
|
28
28
|
# when coming from `recordable_object_changes`, it will be a `HashWithIndifferentAccess`.
|
|
29
29
|
def dump(object)
|
|
30
|
-
object = object.to_hash if object.is_a?(HashWithIndifferentAccess)
|
|
30
|
+
object = object.to_hash if object.is_a?(ActiveSupport::HashWithIndifferentAccess)
|
|
31
31
|
::YAML.dump object
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -320,7 +320,7 @@ module PaperTrail
|
|
|
320
320
|
end
|
|
321
321
|
|
|
322
322
|
# First, deserialize the `object_changes` column.
|
|
323
|
-
changes = HashWithIndifferentAccess.new(object_changes_deserialized)
|
|
323
|
+
changes = ActiveSupport::HashWithIndifferentAccess.new(object_changes_deserialized)
|
|
324
324
|
|
|
325
325
|
# The next step is, perhaps unfortunately, called "de-serialization",
|
|
326
326
|
# and appears to be responsible for custom attribute serializers. For an
|
data/lib/paper_trail.rb
CHANGED
|
@@ -115,10 +115,6 @@ module PaperTrail
|
|
|
115
115
|
VERSION::STRING
|
|
116
116
|
end
|
|
117
117
|
|
|
118
|
-
def active_record_gte_7_0?
|
|
119
|
-
@active_record_gte_7_0 ||= ::ActiveRecord.gem_version >= ::Gem::Version.new("7.0.0")
|
|
120
|
-
end
|
|
121
|
-
|
|
122
118
|
def deprecator
|
|
123
119
|
@deprecator ||= ActiveSupport::Deprecation.new("16.0", "PaperTrail")
|
|
124
120
|
end
|
metadata
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: paper_trail
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 17.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andy Stewart
|
|
8
8
|
- Ben Atkins
|
|
9
9
|
- Jared Beck
|
|
10
|
-
autorequire:
|
|
11
10
|
bindir: bin
|
|
12
11
|
cert_chain: []
|
|
13
|
-
date:
|
|
12
|
+
date: 2025-10-24 00:00:00.000000000 Z
|
|
14
13
|
dependencies:
|
|
15
14
|
- !ruby/object:Gem::Dependency
|
|
16
15
|
name: activerecord
|
|
@@ -18,14 +17,14 @@ dependencies:
|
|
|
18
17
|
requirements:
|
|
19
18
|
- - ">="
|
|
20
19
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: '
|
|
20
|
+
version: '7.1'
|
|
22
21
|
type: :runtime
|
|
23
22
|
prerelease: false
|
|
24
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
24
|
requirements:
|
|
26
25
|
- - ">="
|
|
27
26
|
- !ruby/object:Gem::Version
|
|
28
|
-
version: '
|
|
27
|
+
version: '7.1'
|
|
29
28
|
- !ruby/object:Gem::Dependency
|
|
30
29
|
name: request_store
|
|
31
30
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -40,6 +39,76 @@ dependencies:
|
|
|
40
39
|
- - "~>"
|
|
41
40
|
- !ruby/object:Gem::Version
|
|
42
41
|
version: '1.4'
|
|
42
|
+
- !ruby/object:Gem::Dependency
|
|
43
|
+
name: benchmark
|
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - "~>"
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: 0.4.0
|
|
49
|
+
type: :development
|
|
50
|
+
prerelease: false
|
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - "~>"
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: 0.4.0
|
|
56
|
+
- !ruby/object:Gem::Dependency
|
|
57
|
+
name: bigdecimal
|
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - "~>"
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '3.1'
|
|
63
|
+
type: :development
|
|
64
|
+
prerelease: false
|
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - "~>"
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '3.1'
|
|
70
|
+
- !ruby/object:Gem::Dependency
|
|
71
|
+
name: drb
|
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - "~>"
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '2.2'
|
|
77
|
+
type: :development
|
|
78
|
+
prerelease: false
|
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
80
|
+
requirements:
|
|
81
|
+
- - "~>"
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
version: '2.2'
|
|
84
|
+
- !ruby/object:Gem::Dependency
|
|
85
|
+
name: logger
|
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
|
87
|
+
requirements:
|
|
88
|
+
- - "~>"
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: '1.6'
|
|
91
|
+
type: :development
|
|
92
|
+
prerelease: false
|
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
94
|
+
requirements:
|
|
95
|
+
- - "~>"
|
|
96
|
+
- !ruby/object:Gem::Version
|
|
97
|
+
version: '1.6'
|
|
98
|
+
- !ruby/object:Gem::Dependency
|
|
99
|
+
name: mutex_m
|
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
|
101
|
+
requirements:
|
|
102
|
+
- - "~>"
|
|
103
|
+
- !ruby/object:Gem::Version
|
|
104
|
+
version: 0.3.0
|
|
105
|
+
type: :development
|
|
106
|
+
prerelease: false
|
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
108
|
+
requirements:
|
|
109
|
+
- - "~>"
|
|
110
|
+
- !ruby/object:Gem::Version
|
|
111
|
+
version: 0.3.0
|
|
43
112
|
- !ruby/object:Gem::Dependency
|
|
44
113
|
name: appraisal
|
|
45
114
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -116,14 +185,28 @@ dependencies:
|
|
|
116
185
|
requirements:
|
|
117
186
|
- - ">="
|
|
118
187
|
- !ruby/object:Gem::Version
|
|
119
|
-
version: '
|
|
188
|
+
version: '7.1'
|
|
120
189
|
type: :development
|
|
121
190
|
prerelease: false
|
|
122
191
|
version_requirements: !ruby/object:Gem::Requirement
|
|
123
192
|
requirements:
|
|
124
193
|
- - ">="
|
|
125
194
|
- !ruby/object:Gem::Version
|
|
126
|
-
version: '
|
|
195
|
+
version: '7.1'
|
|
196
|
+
- !ruby/object:Gem::Dependency
|
|
197
|
+
name: rails-controller-testing
|
|
198
|
+
requirement: !ruby/object:Gem::Requirement
|
|
199
|
+
requirements:
|
|
200
|
+
- - "~>"
|
|
201
|
+
- !ruby/object:Gem::Version
|
|
202
|
+
version: 1.0.5
|
|
203
|
+
type: :development
|
|
204
|
+
prerelease: false
|
|
205
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
206
|
+
requirements:
|
|
207
|
+
- - "~>"
|
|
208
|
+
- !ruby/object:Gem::Version
|
|
209
|
+
version: 1.0.5
|
|
127
210
|
- !ruby/object:Gem::Dependency
|
|
128
211
|
name: rake
|
|
129
212
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -144,98 +227,98 @@ dependencies:
|
|
|
144
227
|
requirements:
|
|
145
228
|
- - "~>"
|
|
146
229
|
- !ruby/object:Gem::Version
|
|
147
|
-
version:
|
|
230
|
+
version: 7.1.1
|
|
148
231
|
type: :development
|
|
149
232
|
prerelease: false
|
|
150
233
|
version_requirements: !ruby/object:Gem::Requirement
|
|
151
234
|
requirements:
|
|
152
235
|
- - "~>"
|
|
153
236
|
- !ruby/object:Gem::Version
|
|
154
|
-
version:
|
|
237
|
+
version: 7.1.1
|
|
155
238
|
- !ruby/object:Gem::Dependency
|
|
156
239
|
name: rubocop
|
|
157
240
|
requirement: !ruby/object:Gem::Requirement
|
|
158
241
|
requirements:
|
|
159
242
|
- - "~>"
|
|
160
243
|
- !ruby/object:Gem::Version
|
|
161
|
-
version: 1.
|
|
244
|
+
version: '1.75'
|
|
162
245
|
type: :development
|
|
163
246
|
prerelease: false
|
|
164
247
|
version_requirements: !ruby/object:Gem::Requirement
|
|
165
248
|
requirements:
|
|
166
249
|
- - "~>"
|
|
167
250
|
- !ruby/object:Gem::Version
|
|
168
|
-
version: 1.
|
|
251
|
+
version: '1.75'
|
|
169
252
|
- !ruby/object:Gem::Dependency
|
|
170
253
|
name: rubocop-packaging
|
|
171
254
|
requirement: !ruby/object:Gem::Requirement
|
|
172
255
|
requirements:
|
|
173
256
|
- - "~>"
|
|
174
257
|
- !ruby/object:Gem::Version
|
|
175
|
-
version: 0.
|
|
258
|
+
version: 0.6.0
|
|
176
259
|
type: :development
|
|
177
260
|
prerelease: false
|
|
178
261
|
version_requirements: !ruby/object:Gem::Requirement
|
|
179
262
|
requirements:
|
|
180
263
|
- - "~>"
|
|
181
264
|
- !ruby/object:Gem::Version
|
|
182
|
-
version: 0.
|
|
265
|
+
version: 0.6.0
|
|
183
266
|
- !ruby/object:Gem::Dependency
|
|
184
267
|
name: rubocop-performance
|
|
185
268
|
requirement: !ruby/object:Gem::Requirement
|
|
186
269
|
requirements:
|
|
187
270
|
- - "~>"
|
|
188
271
|
- !ruby/object:Gem::Version
|
|
189
|
-
version: 1.
|
|
272
|
+
version: 1.24.0
|
|
190
273
|
type: :development
|
|
191
274
|
prerelease: false
|
|
192
275
|
version_requirements: !ruby/object:Gem::Requirement
|
|
193
276
|
requirements:
|
|
194
277
|
- - "~>"
|
|
195
278
|
- !ruby/object:Gem::Version
|
|
196
|
-
version: 1.
|
|
279
|
+
version: 1.24.0
|
|
197
280
|
- !ruby/object:Gem::Dependency
|
|
198
281
|
name: rubocop-rails
|
|
199
282
|
requirement: !ruby/object:Gem::Requirement
|
|
200
283
|
requirements:
|
|
201
284
|
- - "~>"
|
|
202
285
|
- !ruby/object:Gem::Version
|
|
203
|
-
version: 2.
|
|
286
|
+
version: 2.30.3
|
|
204
287
|
type: :development
|
|
205
288
|
prerelease: false
|
|
206
289
|
version_requirements: !ruby/object:Gem::Requirement
|
|
207
290
|
requirements:
|
|
208
291
|
- - "~>"
|
|
209
292
|
- !ruby/object:Gem::Version
|
|
210
|
-
version: 2.
|
|
293
|
+
version: 2.30.3
|
|
211
294
|
- !ruby/object:Gem::Dependency
|
|
212
295
|
name: rubocop-rake
|
|
213
296
|
requirement: !ruby/object:Gem::Requirement
|
|
214
297
|
requirements:
|
|
215
298
|
- - "~>"
|
|
216
299
|
- !ruby/object:Gem::Version
|
|
217
|
-
version: 0.
|
|
300
|
+
version: 0.7.1
|
|
218
301
|
type: :development
|
|
219
302
|
prerelease: false
|
|
220
303
|
version_requirements: !ruby/object:Gem::Requirement
|
|
221
304
|
requirements:
|
|
222
305
|
- - "~>"
|
|
223
306
|
- !ruby/object:Gem::Version
|
|
224
|
-
version: 0.
|
|
307
|
+
version: 0.7.1
|
|
225
308
|
- !ruby/object:Gem::Dependency
|
|
226
309
|
name: rubocop-rspec
|
|
227
310
|
requirement: !ruby/object:Gem::Requirement
|
|
228
311
|
requirements:
|
|
229
312
|
- - "~>"
|
|
230
313
|
- !ruby/object:Gem::Version
|
|
231
|
-
version:
|
|
314
|
+
version: 3.5.0
|
|
232
315
|
type: :development
|
|
233
316
|
prerelease: false
|
|
234
317
|
version_requirements: !ruby/object:Gem::Requirement
|
|
235
318
|
requirements:
|
|
236
319
|
- - "~>"
|
|
237
320
|
- !ruby/object:Gem::Version
|
|
238
|
-
version:
|
|
321
|
+
version: 3.5.0
|
|
239
322
|
- !ruby/object:Gem::Dependency
|
|
240
323
|
name: simplecov
|
|
241
324
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -353,7 +436,7 @@ licenses:
|
|
|
353
436
|
- MIT
|
|
354
437
|
metadata:
|
|
355
438
|
changelog_uri: https://github.com/paper-trail-gem/paper_trail/blob/master/CHANGELOG.md
|
|
356
|
-
|
|
439
|
+
rubygems_mfa_required: 'true'
|
|
357
440
|
rdoc_options: []
|
|
358
441
|
require_paths:
|
|
359
442
|
- lib
|
|
@@ -361,15 +444,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
361
444
|
requirements:
|
|
362
445
|
- - ">="
|
|
363
446
|
- !ruby/object:Gem::Version
|
|
364
|
-
version: 3.
|
|
447
|
+
version: 3.2.0
|
|
365
448
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
366
449
|
requirements:
|
|
367
450
|
- - ">="
|
|
368
451
|
- !ruby/object:Gem::Version
|
|
369
452
|
version: 1.3.6
|
|
370
453
|
requirements: []
|
|
371
|
-
rubygems_version: 3.
|
|
372
|
-
signing_key:
|
|
454
|
+
rubygems_version: 3.6.2
|
|
373
455
|
specification_version: 4
|
|
374
456
|
summary: Track changes to your models.
|
|
375
457
|
test_files: []
|