paper_trail 12.0.0 → 12.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2ce7f019e3413c485beff4eefa957f759b084fe0d29b0d9f3451b6ba3e4befe
4
- data.tar.gz: 3f73870b42c582f683936eee21fe288b17d915d1bfbff5327ac50dd8e9766732
3
+ metadata.gz: 7e29e666977c2b4072eab98684b884cb43dba15e85367eb8221b9294ebad945c
4
+ data.tar.gz: 750c5670a52675ab4dcc17bfd5389eaf87ebe4d4a3a68ccbb7ed2da1bd43e52f
5
5
  SHA512:
6
- metadata.gz: 6134547d0c2c69f94962aea4f868aec8d456bbb0afc4588b9b07971074a8d50476f29a59acb41d3e058dea581678d0c7129d8e92a04c370fa2016dbd6bf544b7
7
- data.tar.gz: a6ca4e41cf2f6bce774894a9927dc0b3e4abbcbbdbb39fbf4671d029398f26999ce8927143f1f14279a6ad8aa70194025f5b6e653780560a0cc4870dce9b754e
6
+ metadata.gz: b44b40b4683d987d67faf3fabb87d603cd6d99dad2c0c3b6b2859c5d30fd862fe3058e2fa1a1cea982a15ec45a4b8b194a55590b8d523aa8630d3b0644374b8e
7
+ data.tar.gz: '0882176106dfa57ce49b0cf0c1267e2465e134a07719fc3436beec7cad5e10a23c6ff7d409b3332123cf8a5b7ce99e854351e4d60072894026027772f1cc14e8'
@@ -7,8 +7,10 @@ module PaperTrail
7
7
  class UpdateItemSubtypeGenerator < MigrationGenerator
8
8
  source_root File.expand_path("templates", __dir__)
9
9
 
10
- desc "Generates (but does not run) a migration to update item_subtype for STI entries in an "\
11
- "existing versions table."
10
+ desc(
11
+ "Generates (but does not run) a migration to update item_subtype for "\
12
+ "STI entries in an existing versions table."
13
+ )
12
14
 
13
15
  def create_migration_file
14
16
  add_paper_trail_migration("update_versions_for_item_subtype", sti_type_options: options)
@@ -18,7 +18,7 @@ module PaperTrail
18
18
  # versions.
19
19
  module Compatibility
20
20
  ACTIVERECORD_GTE = ">= 5.2" # enforced in gemspec
21
- ACTIVERECORD_LT = "< 6.2" # not enforced in gemspec
21
+ ACTIVERECORD_LT = "< 7.0" # 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
@@ -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
@@ -109,19 +109,11 @@ module PaperTrail
109
109
  @changed_in_latest_version ||= changes_in_latest_version.keys
110
110
  end
111
111
 
112
- # Rails 5.1 changed the API of `ActiveRecord::Dirty`. See
113
- # https://github.com/paper-trail-gem/paper_trail/pull/899
112
+ # Memoized to reduce memory usage
114
113
  #
115
114
  # @api private
116
115
  def changes_in_latest_version
117
- # Memoized to reduce memory usage
118
- @changes_in_latest_version ||= begin
119
- if @in_after_callback
120
- @record.saved_changes
121
- else
122
- @record.changes
123
- end
124
- end
116
+ @changes_in_latest_version ||= load_changes_in_latest_version
125
117
  end
126
118
 
127
119
  # An attributed is "ignored" if it is listed in the `:ignore` option
@@ -134,6 +126,18 @@ module PaperTrail
134
126
  ignored.any? && (changed_in_latest_version & ignored).any?
135
127
  end
136
128
 
129
+ # Rails 5.1 changed the API of `ActiveRecord::Dirty`. See
130
+ # https://github.com/paper-trail-gem/paper_trail/pull/899
131
+ #
132
+ # @api private
133
+ def load_changes_in_latest_version
134
+ if @in_after_callback
135
+ @record.saved_changes
136
+ else
137
+ @record.changes
138
+ end
139
+ end
140
+
137
141
  # PT 10 has a new optional column, `item_subtype`
138
142
  #
139
143
  # @api private
@@ -18,11 +18,6 @@ module PaperTrail
18
18
  `abstract_class`. This is fine, but all application models must be
19
19
  configured to use concrete (not abstract) version models.
20
20
  STR
21
- E_MODEL_LIMIT_REQUIRES_ITEM_SUBTYPE = <<~STR.squish.freeze
22
- To use PaperTrail's per-model limit in your %s model, you must have an
23
- item_subtype column in your versions table. See documentation sections
24
- 2.e.1 Per-model limit, and 4.b.1 The optional item_subtype column.
25
- STR
26
21
  DPR_PASSING_ASSOC_NAME_DIRECTLY_TO_VERSIONS_OPTION = <<~STR.squish
27
22
  Passing versions association name as `has_paper_trail versions: %{versions_name}`
28
23
  is deprecated. Use `has_paper_trail versions: {name: %{versions_name}}` instead.
@@ -53,13 +48,7 @@ module PaperTrail
53
48
  #
54
49
  # @api public
55
50
  def on_destroy(recording_order = "before")
56
- unless %w[after before].include?(recording_order.to_s)
57
- raise ArgumentError, 'recording order can only be "after" or "before"'
58
- end
59
-
60
- if recording_order.to_s == "after" && cannot_record_after_destroy?
61
- raise E_CANNOT_RECORD_AFTER_DESTROY
62
- end
51
+ assert_valid_recording_order_for_on_destroy(recording_order)
63
52
 
64
53
  @model_class.send(
65
54
  "#{recording_order}_destroy",
@@ -97,11 +86,18 @@ module PaperTrail
97
86
  end
98
87
 
99
88
  # Adds a callback that records a version after a "touch" event.
89
+ #
90
+ # Rails < 6.0 has a bug where dirty-tracking does not occur during
91
+ # a `touch`. (https://github.com/rails/rails/issues/33429) See also:
92
+ # https://github.com/paper-trail-gem/paper_trail/issues/1121
93
+ # https://github.com/paper-trail-gem/paper_trail/issues/1161
94
+ # https://github.com/paper-trail-gem/paper_trail/pull/1285
95
+ #
100
96
  # @api public
101
97
  def on_touch
102
98
  @model_class.after_touch { |r|
103
99
  r.paper_trail.record_update(
104
- force: true,
100
+ force: RAILS_LT_6_0,
105
101
  in_after_callback: true,
106
102
  is_touch: true
107
103
  )
@@ -117,7 +113,6 @@ module PaperTrail
117
113
  @model_class.send :include, ::PaperTrail::Model::InstanceMethods
118
114
  setup_options(options)
119
115
  setup_associations(options)
120
- check_presence_of_item_subtype_column(options)
121
116
  @model_class.after_rollback { paper_trail.clear_rolled_back_versions }
122
117
  setup_callbacks_from_options options[:on]
123
118
  end
@@ -129,26 +124,30 @@ module PaperTrail
129
124
 
130
125
  private
131
126
 
127
+ RAILS_LT_6_0 = ::ActiveRecord.gem_version < ::Gem::Version.new("6.0.0")
128
+ private_constant :RAILS_LT_6_0
129
+
132
130
  # Raises an error if the provided class is an `abstract_class`.
133
131
  # @api private
134
132
  def assert_concrete_activerecord_class(class_name)
135
133
  if class_name.constantize.abstract_class?
136
- raise format(E_HPT_ABSTRACT_CLASS, @model_class, class_name)
134
+ raise Error, format(E_HPT_ABSTRACT_CLASS, @model_class, class_name)
137
135
  end
138
136
  end
139
137
 
140
- def cannot_record_after_destroy?
141
- ::ActiveRecord::Base.belongs_to_required_by_default
138
+ # @api private
139
+ def assert_valid_recording_order_for_on_destroy(recording_order)
140
+ unless %w[after before].include?(recording_order.to_s)
141
+ raise ArgumentError, 'recording order can only be "after" or "before"'
142
+ end
143
+
144
+ if recording_order.to_s == "after" && cannot_record_after_destroy?
145
+ raise Error, E_CANNOT_RECORD_AFTER_DESTROY
146
+ end
142
147
  end
143
148
 
144
- # Some options require the presence of the `item_subtype` column. Currently
145
- # only `limit`, but in the future there may be others.
146
- #
147
- # @api private
148
- def check_presence_of_item_subtype_column(options)
149
- return unless options.key?(:limit)
150
- return if version_class.item_subtype_column_present?
151
- raise format(E_MODEL_LIMIT_REQUIRES_ITEM_SUBTYPE, @model_class.name)
149
+ def cannot_record_after_destroy?
150
+ ::ActiveRecord::Base.belongs_to_required_by_default
152
151
  end
153
152
 
154
153
  def check_version_class_name(options)
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaperTrail
4
+ module Queries
5
+ module Versions
6
+ # For public API documentation, see `where_attribute_changes` in
7
+ # `paper_trail/version_concern.rb`.
8
+ # @api private
9
+ class WhereAttributeChanges
10
+ # - version_model_class - The class that VersionConcern was mixed into.
11
+ # - attribute - An attribute that changed. See the public API
12
+ # documentation for details.
13
+ # @api private
14
+ def initialize(version_model_class, attribute)
15
+ @version_model_class = version_model_class
16
+ @attribute = attribute
17
+ end
18
+
19
+ # @api private
20
+ def execute
21
+ if PaperTrail.config.object_changes_adapter.respond_to?(:where_attribute_changes)
22
+ return PaperTrail.config.object_changes_adapter.where_attribute_changes(
23
+ @version_model_class, @attribute
24
+ )
25
+ end
26
+ column_type = @version_model_class.columns_hash["object_changes"].type
27
+ case column_type
28
+ when :jsonb, :json
29
+ json
30
+ else
31
+ raise UnsupportedColumnType.new(
32
+ method: "where_attribute_changes",
33
+ expected: "json or jsonb",
34
+ actual: column_type
35
+ )
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ # @api private
42
+ def json
43
+ sql = "object_changes -> ? IS NOT NULL"
44
+
45
+ @version_model_class.where(sql, @attribute)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -19,7 +19,7 @@ module PaperTrail
19
19
  # @api private
20
20
  def execute
21
21
  column = @version_model_class.columns_hash["object"]
22
- raise "where_object can't be called without an object column" unless column
22
+ raise Error, "where_object requires an object column" unless column
23
23
 
24
24
  case column.type
25
25
  when :jsonb
@@ -28,13 +28,18 @@ module PaperTrail
28
28
  @version_model_class, @attributes
29
29
  )
30
30
  end
31
- case @version_model_class.columns_hash["object_changes"].type
31
+ column_type = @version_model_class.columns_hash["object_changes"].type
32
+ case column_type
32
33
  when :jsonb
33
34
  jsonb
34
35
  when :json
35
36
  json
36
37
  else
37
- text
38
+ raise UnsupportedColumnType.new(
39
+ method: "where_object_changes",
40
+ expected: "json or jsonb",
41
+ actual: column_type
42
+ )
38
43
  end
39
44
  end
40
45
 
@@ -59,16 +64,6 @@ module PaperTrail
59
64
  @attributes.each { |field, value| @attributes[field] = [value] }
60
65
  @version_model_class.where("object_changes @> ?", @attributes.to_json)
61
66
  end
62
-
63
- # @api private
64
- def text
65
- arel_field = @version_model_class.arel_table[:object_changes]
66
- where_conditions = @attributes.map { |field, value|
67
- ::PaperTrail.serializer.where_object_changes_condition(arel_field, field, value)
68
- }
69
- where_conditions = where_conditions.reduce { |a, e| a.and(e) }
70
- @version_model_class.where(where_conditions)
71
- end
72
67
  end
73
68
  end
74
69
  end
@@ -23,12 +23,16 @@ module PaperTrail
23
23
  @version_model_class, @attributes
24
24
  )
25
25
  end
26
-
27
- case @version_model_class.columns_hash["object_changes"].type
26
+ column_type = @version_model_class.columns_hash["object_changes"].type
27
+ case column_type
28
28
  when :jsonb, :json
29
29
  json
30
30
  else
31
- text
31
+ raise UnsupportedColumnType.new(
32
+ method: "where_object_changes_from",
33
+ expected: "json or jsonb",
34
+ actual: column_type
35
+ )
32
36
  end
33
37
  end
34
38
 
@@ -47,18 +51,6 @@ module PaperTrail
47
51
  sql = predicates.join(" and ")
48
52
  @version_model_class.where(sql, *values)
49
53
  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
54
  end
63
55
  end
64
56
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaperTrail
4
+ module Queries
5
+ module Versions
6
+ # For public API documentation, see `where_object_changes_to` in
7
+ # `paper_trail/version_concern.rb`.
8
+ # @api private
9
+ class WhereObjectChangesTo
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_to)
22
+ return PaperTrail.config.object_changes_adapter.where_object_changes_to(
23
+ @version_model_class, @attributes
24
+ )
25
+ end
26
+ column_type = @version_model_class.columns_hash["object_changes"].type
27
+ case column_type
28
+ when :jsonb, :json
29
+ json
30
+ else
31
+ raise UnsupportedColumnType.new(
32
+ method: "where_object_changes_to",
33
+ expected: "json or jsonb",
34
+ actual: column_type
35
+ )
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ # @api private
42
+ def json
43
+ predicates = []
44
+ values = []
45
+ @attributes.each do |field, value|
46
+ predicates.push(
47
+ "(object_changes->>? ILIKE ?)"
48
+ )
49
+ values.concat([field, "[%#{value.to_json}]"])
50
+ end
51
+ sql = predicates.join(" and ")
52
+ @version_model_class.where(sql, *values)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -283,7 +283,7 @@ module PaperTrail
283
283
  def log_version_errors(version, action)
284
284
  version.logger&.warn(
285
285
  "Unable to create version for #{action} of #{@record.class.name}" \
286
- "##{@record.id}: " + version.errors.full_messages.join(", ")
286
+ "##{@record.id}: " + version.errors.full_messages.join(", ")
287
287
  )
288
288
  end
289
289
 
@@ -60,9 +60,7 @@ module PaperTrail
60
60
  model = if options[:dup] == true || version.event == "destroy"
61
61
  klass.new
62
62
  else
63
- find_cond = { klass.primary_key => version.item_id }
64
-
65
- version.item || klass.unscoped.where(find_cond).first || klass.new
63
+ version.item || init_model_by_finding_item_id(klass, version) || klass.new
66
64
  end
67
65
 
68
66
  if options[:unversioned_attributes] == :nil && !model.new_record?
@@ -72,6 +70,11 @@ module PaperTrail
72
70
  model
73
71
  end
74
72
 
73
+ # @api private
74
+ def init_model_by_finding_item_id(klass, version)
75
+ klass.unscoped.where(klass.primary_key => version.item_id).first
76
+ end
77
+
75
78
  # Look for attributes that exist in `model` and not in this version.
76
79
  # These attributes should be set to nil. Modifies `attrs`.
77
80
  # @api private
@@ -109,21 +112,35 @@ module PaperTrail
109
112
  end
110
113
 
111
114
  # Given a `version`, return the class to reify. This method supports
112
- # Single Table Inheritance (STI) with custom inheritance columns.
115
+ # Single Table Inheritance (STI) with custom inheritance columns and
116
+ # custom inheritance column values.
113
117
  #
114
118
  # For example, imagine a `version` whose `item_type` is "Animal". The
115
119
  # `animals` table is an STI table (it has cats and dogs) and it has a
116
120
  # custom inheritance column, `species`. If `attrs["species"]` is "Dog",
117
121
  # this method returns the constant `Dog`. If `attrs["species"]` is blank,
118
- # this method returns the constant `Animal`. You can see this particular
119
- # example in action in `spec/models/animal_spec.rb`.
122
+ # this method returns the constant `Animal`.
120
123
  #
121
- # TODO: Duplication: similar `constantize` in VersionConcern#version_limit
124
+ # The values contained in the inheritance columns may be non-camelized
125
+ # strings (e.g. 'dog' instead of 'Dog'). To reify classes in this case
126
+ # we need to call the parents class `sti_class_for` method to retrieve
127
+ # the correct record class.
128
+ #
129
+ # You can see these particular examples in action in
130
+ # `spec/models/animal_spec.rb` and `spec/models/plant_spec.rb`
122
131
  def version_reification_class(version, attrs)
123
- inheritance_column_name = version.item_type.constantize.inheritance_column
132
+ clazz = version.item_type.constantize
133
+ inheritance_column_name = clazz.inheritance_column
124
134
  inher_col_value = attrs[inheritance_column_name]
125
- class_name = inher_col_value.blank? ? version.item_type : inher_col_value
126
- class_name.constantize
135
+ return clazz if inher_col_value.blank?
136
+
137
+ # Rails 6.1 adds a public method for clients to use to customize STI classes. If that
138
+ # method is not available, fall back to using the private one
139
+ if clazz.public_methods.include?(:sti_class_for)
140
+ return clazz.sti_class_for(inher_col_value)
141
+ end
142
+
143
+ clazz.send(:find_sti_class, inher_col_value)
127
144
  end
128
145
  end
129
146
  end
@@ -12,9 +12,6 @@ module PaperTrail
12
12
  #
13
13
  # @api private
14
14
  module Request
15
- class InvalidOption < RuntimeError
16
- end
17
-
18
15
  class << self
19
16
  # Sets any data from the controller that you want PaperTrail to store.
20
17
  # See also `PaperTrail::Rails::Controller#info_for_paper_trail`.
@@ -31,24 +31,6 @@ module PaperTrail
31
31
  arel_field.matches("%\"#{field}\":#{json_value}%")
32
32
  end
33
33
  end
34
-
35
- def where_object_changes_condition(*)
36
- raise <<-STR.squish.freeze
37
- where_object_changes no longer supports reading JSON from a text
38
- column. The old implementation was inaccurate, returning more records
39
- than you wanted. This feature was deprecated in 7.1.0 and removed in
40
- 8.0.0. The json and jsonb datatypes are still supported. See the
41
- discussion at https://github.com/paper-trail-gem/paper_trail/issues/803
42
- STR
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
52
34
  end
53
35
  end
54
36
  end
@@ -26,26 +26,6 @@ module PaperTrail
26
26
  def where_object_condition(arel_field, field, value)
27
27
  arel_field.matches("%\n#{field}: #{value}\n%")
28
28
  end
29
-
30
- # Returns a SQL LIKE condition to be used to match the given field and
31
- # value in the serialized `object_changes`.
32
- def where_object_changes_condition(*)
33
- raise <<-STR.squish.freeze
34
- where_object_changes no longer supports reading YAML from a text
35
- column. The old implementation was inaccurate, returning more records
36
- than you wanted. This feature was deprecated in 8.1.0 and removed in
37
- 9.0.0. The json and jsonb datatypes are still supported. See
38
- discussion at https://github.com/paper-trail-gem/paper_trail/pull/997
39
- STR
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
49
29
  end
50
30
  end
51
31
  end
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "paper_trail/attribute_serializers/object_changes_attribute"
4
+ require "paper_trail/queries/versions/where_attribute_changes"
4
5
  require "paper_trail/queries/versions/where_object"
5
6
  require "paper_trail/queries/versions/where_object_changes"
6
7
  require "paper_trail/queries/versions/where_object_changes_from"
8
+ require "paper_trail/queries/versions/where_object_changes_to"
7
9
 
8
10
  module PaperTrail
9
11
  # Originally, PaperTrail did not provide this module, and all of this
@@ -21,10 +23,6 @@ module PaperTrail
21
23
 
22
24
  # :nodoc:
23
25
  module ClassMethods
24
- def item_subtype_column_present?
25
- column_names.include?("item_subtype")
26
- end
27
-
28
26
  def with_item_keys(item_type, item_id)
29
27
  where item_type: item_type, item_id: item_id
30
28
  end
@@ -42,7 +40,7 @@ module PaperTrail
42
40
  end
43
41
 
44
42
  def not_creates
45
- where "event <> ?", "create"
43
+ where.not(event: "create")
46
44
  end
47
45
 
48
46
  def between(start_time, end_time)
@@ -60,6 +58,18 @@ module PaperTrail
60
58
  end
61
59
  end
62
60
 
61
+ # Given an attribute like `"name"`, query the `versions.object_changes`
62
+ # column for any changes that modified the provided attribute.
63
+ #
64
+ # @api public
65
+ def where_attribute_changes(attribute)
66
+ unless attribute.is_a?(String) || attribute.is_a?(Symbol)
67
+ raise ArgumentError, "expected to receive a String or Symbol"
68
+ end
69
+
70
+ Queries::Versions::WhereAttributeChanges.new(self, attribute).execute
71
+ end
72
+
63
73
  # Given a hash of attributes like `name: 'Joan'`, query the
64
74
  # `versions.objects` column.
65
75
  #
@@ -131,6 +141,21 @@ module PaperTrail
131
141
  Queries::Versions::WhereObjectChangesFrom.new(self, args).execute
132
142
  end
133
143
 
144
+ # Given a hash of attributes like `name: 'Joan'`, query the
145
+ # `versions.objects_changes` column for changes where the version changed
146
+ # to the hash of attributes from other values.
147
+ #
148
+ # This is useful for finding versions where the attribute started with an
149
+ # unknown value and changed to a known value. This is in comparison to
150
+ # `where_object_changes` which will find both the changes before and
151
+ # after.
152
+ #
153
+ # @api public
154
+ def where_object_changes_to(args = {})
155
+ raise ArgumentError, "expected to receive a Hash" unless args.is_a?(Hash)
156
+ Queries::Versions::WhereObjectChangesTo.new(self, args).execute
157
+ end
158
+
134
159
  def primary_key_is_int?
135
160
  @primary_key_is_int ||= columns_hash[primary_key].type == :integer
136
161
  rescue StandardError # TODO: Rescue something more specific
@@ -237,7 +262,7 @@ module PaperTrail
237
262
  #
238
263
  def reify(options = {})
239
264
  unless self.class.column_names.include? "object"
240
- raise "reify can't be called without an object column"
265
+ raise Error, "reify requires an object column"
241
266
  end
242
267
  return nil if object.nil?
243
268
  ::PaperTrail::Reifier.reify(self, options)
@@ -350,16 +375,22 @@ module PaperTrail
350
375
  # The version limit can be global or per-model.
351
376
  #
352
377
  # @api private
353
- #
354
- # TODO: Duplication: similar `constantize` in Reifier#version_reification_class
355
378
  def version_limit
356
- if self.class.item_subtype_column_present?
357
- klass = (item_subtype || item_type).constantize
358
- if klass&.paper_trail_options&.key?(:limit)
359
- return klass.paper_trail_options[:limit]
360
- end
379
+ if limit_option?(item.class)
380
+ item.class.paper_trail_options[:limit]
381
+ elsif base_class_limit_option?(item.class)
382
+ item.class.base_class.paper_trail_options[:limit]
383
+ else
384
+ PaperTrail.config.version_limit
361
385
  end
362
- PaperTrail.config.version_limit
386
+ end
387
+
388
+ def limit_option?(klass)
389
+ klass.respond_to?(:paper_trail_options) && klass.paper_trail_options.key?(:limit)
390
+ end
391
+
392
+ def base_class_limit_option?(klass)
393
+ klass.respond_to?(:base_class) && limit_option?(klass.base_class)
363
394
  end
364
395
  end
365
396
  end
@@ -8,7 +8,7 @@ module PaperTrail
8
8
  # People are encouraged to use `PaperTrail.gem_version` instead.
9
9
  module VERSION
10
10
  MAJOR = 12
11
- MINOR = 0
11
+ MINOR = 1
12
12
  TINY = 0
13
13
 
14
14
  # Set PRE to nil unless it's a pre-release (beta, rc, etc.)
data/lib/paper_trail.rb CHANGED
@@ -8,6 +8,7 @@
8
8
  # can revisit this decision.
9
9
  require "active_support/all"
10
10
 
11
+ require "paper_trail/errors"
11
12
  require "paper_trail/cleaner"
12
13
  require "paper_trail/compatibility"
13
14
  require "paper_trail/config"
@@ -68,7 +69,7 @@ module PaperTrail
68
69
  #
69
70
  # @api public
70
71
  def request(options = nil, &block)
71
- if options.nil? && !block_given?
72
+ if options.nil? && !block
72
73
  Request
73
74
  else
74
75
  Request.with(options, &block)
@@ -78,7 +79,7 @@ module PaperTrail
78
79
  # Set the field which records when a version was created.
79
80
  # @api public
80
81
  def timestamp_field=(_field_name)
81
- raise(E_TIMESTAMP_FIELD_CONFIG)
82
+ raise Error, E_TIMESTAMP_FIELD_CONFIG
82
83
  end
83
84
 
84
85
  # Set the PaperTrail serializer. This setting affects all threads.
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: 12.0.0
4
+ version: 12.1.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: 2021-03-29 00:00:00.000000000 Z
13
+ date: 2021-08-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -46,14 +46,14 @@ dependencies:
46
46
  requirements:
47
47
  - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: '2.2'
49
+ version: 2.4.1
50
50
  type: :development
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
54
  - - "~>"
55
55
  - !ruby/object:Gem::Version
56
- version: '2.2'
56
+ version: 2.4.1
57
57
  - !ruby/object:Gem::Dependency
58
58
  name: byebug
59
59
  requirement: !ruby/object:Gem::Requirement
@@ -74,14 +74,14 @@ dependencies:
74
74
  requirements:
75
75
  - - "~>"
76
76
  - !ruby/object:Gem::Version
77
- version: '2.11'
77
+ version: 2.19.0
78
78
  type: :development
79
79
  prerelease: false
80
80
  version_requirements: !ruby/object:Gem::Requirement
81
81
  requirements:
82
82
  - - "~>"
83
83
  - !ruby/object:Gem::Version
84
- version: '2.11'
84
+ version: 2.19.0
85
85
  - !ruby/object:Gem::Dependency
86
86
  name: generator_spec
87
87
  requirement: !ruby/object:Gem::Requirement
@@ -102,14 +102,14 @@ dependencies:
102
102
  requirements:
103
103
  - - "~>"
104
104
  - !ruby/object:Gem::Version
105
- version: 0.9.14
105
+ version: 1.0.0
106
106
  type: :development
107
107
  prerelease: false
108
108
  version_requirements: !ruby/object:Gem::Requirement
109
109
  requirements:
110
110
  - - "~>"
111
111
  - !ruby/object:Gem::Version
112
- version: 0.9.14
112
+ version: 1.0.0
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: rails
115
115
  requirement: !ruby/object:Gem::Requirement
@@ -144,84 +144,118 @@ dependencies:
144
144
  requirements:
145
145
  - - "~>"
146
146
  - !ruby/object:Gem::Version
147
- version: '4.0'
147
+ version: 5.0.2
148
148
  type: :development
149
149
  prerelease: false
150
150
  version_requirements: !ruby/object:Gem::Requirement
151
151
  requirements:
152
152
  - - "~>"
153
153
  - !ruby/object:Gem::Version
154
- version: '4.0'
154
+ version: 5.0.2
155
155
  - !ruby/object:Gem::Dependency
156
156
  name: rubocop
157
157
  requirement: !ruby/object:Gem::Requirement
158
158
  requirements:
159
159
  - - "~>"
160
160
  - !ruby/object:Gem::Version
161
- version: 1.11.0
161
+ version: 1.20.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: 1.11.0
168
+ version: 1.20.0
169
169
  - !ruby/object:Gem::Dependency
170
- name: rubocop-rails
170
+ name: rubocop-packaging
171
171
  requirement: !ruby/object:Gem::Requirement
172
172
  requirements:
173
173
  - - "~>"
174
174
  - !ruby/object:Gem::Version
175
- version: 2.9.1
175
+ version: 0.5.1
176
176
  type: :development
177
177
  prerelease: false
178
178
  version_requirements: !ruby/object:Gem::Requirement
179
179
  requirements:
180
180
  - - "~>"
181
181
  - !ruby/object:Gem::Version
182
- version: 2.9.1
182
+ version: 0.5.1
183
183
  - !ruby/object:Gem::Dependency
184
- name: rubocop-packaging
184
+ name: rubocop-performance
185
185
  requirement: !ruby/object:Gem::Requirement
186
186
  requirements:
187
187
  - - "~>"
188
188
  - !ruby/object:Gem::Version
189
- version: 0.5.1
189
+ version: 1.11.5
190
190
  type: :development
191
191
  prerelease: false
192
192
  version_requirements: !ruby/object:Gem::Requirement
193
193
  requirements:
194
194
  - - "~>"
195
195
  - !ruby/object:Gem::Version
196
- version: 0.5.1
196
+ version: 1.11.5
197
197
  - !ruby/object:Gem::Dependency
198
- name: rubocop-performance
198
+ name: rubocop-rails
199
+ requirement: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - "~>"
202
+ - !ruby/object:Gem::Version
203
+ version: 2.11.3
204
+ type: :development
205
+ prerelease: false
206
+ version_requirements: !ruby/object:Gem::Requirement
207
+ requirements:
208
+ - - "~>"
209
+ - !ruby/object:Gem::Version
210
+ version: 2.11.3
211
+ - !ruby/object:Gem::Dependency
212
+ name: rubocop-rake
199
213
  requirement: !ruby/object:Gem::Requirement
200
214
  requirements:
201
215
  - - "~>"
202
216
  - !ruby/object:Gem::Version
203
- version: 1.10.1
217
+ version: 0.6.0
204
218
  type: :development
205
219
  prerelease: false
206
220
  version_requirements: !ruby/object:Gem::Requirement
207
221
  requirements:
208
222
  - - "~>"
209
223
  - !ruby/object:Gem::Version
210
- version: 1.10.1
224
+ version: 0.6.0
211
225
  - !ruby/object:Gem::Dependency
212
226
  name: rubocop-rspec
213
227
  requirement: !ruby/object:Gem::Requirement
214
228
  requirements:
215
229
  - - "~>"
216
230
  - !ruby/object:Gem::Version
217
- version: 2.2.0
231
+ version: 2.4.0
218
232
  type: :development
219
233
  prerelease: false
220
234
  version_requirements: !ruby/object:Gem::Requirement
221
235
  requirements:
222
236
  - - "~>"
223
237
  - !ruby/object:Gem::Version
224
- version: 2.2.0
238
+ version: 2.4.0
239
+ - !ruby/object:Gem::Dependency
240
+ name: simplecov
241
+ requirement: !ruby/object:Gem::Requirement
242
+ requirements:
243
+ - - ">="
244
+ - !ruby/object:Gem::Version
245
+ version: '0.21'
246
+ - - "<"
247
+ - !ruby/object:Gem::Version
248
+ version: '0.22'
249
+ type: :development
250
+ prerelease: false
251
+ version_requirements: !ruby/object:Gem::Requirement
252
+ requirements:
253
+ - - ">="
254
+ - !ruby/object:Gem::Version
255
+ version: '0.21'
256
+ - - "<"
257
+ - !ruby/object:Gem::Version
258
+ version: '0.22'
225
259
  - !ruby/object:Gem::Dependency
226
260
  name: mysql2
227
261
  requirement: !ruby/object:Gem::Requirement
@@ -297,6 +331,7 @@ files:
297
331
  - lib/paper_trail/cleaner.rb
298
332
  - lib/paper_trail/compatibility.rb
299
333
  - lib/paper_trail/config.rb
334
+ - lib/paper_trail/errors.rb
300
335
  - lib/paper_trail/events/base.rb
301
336
  - lib/paper_trail/events/create.rb
302
337
  - lib/paper_trail/events/destroy.rb
@@ -311,9 +346,11 @@ files:
311
346
  - lib/paper_trail/frameworks/rspec/helpers.rb
312
347
  - lib/paper_trail/has_paper_trail.rb
313
348
  - lib/paper_trail/model_config.rb
349
+ - lib/paper_trail/queries/versions/where_attribute_changes.rb
314
350
  - lib/paper_trail/queries/versions/where_object.rb
315
351
  - lib/paper_trail/queries/versions/where_object_changes.rb
316
352
  - lib/paper_trail/queries/versions/where_object_changes_from.rb
353
+ - lib/paper_trail/queries/versions/where_object_changes_to.rb
317
354
  - lib/paper_trail/record_history.rb
318
355
  - lib/paper_trail/record_trail.rb
319
356
  - lib/paper_trail/reifier.rb
@@ -342,8 +379,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
342
379
  - !ruby/object:Gem::Version
343
380
  version: 1.3.6
344
381
  requirements: []
345
- rubyforge_project:
346
- rubygems_version: 2.7.6.2
382
+ rubygems_version: 3.2.22
347
383
  signing_key:
348
384
  specification_version: 4
349
385
  summary: Track changes to your models.