mongo_trails 10.3.1 → 14.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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +53 -0
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +19 -0
  5. data/.ruby-version +1 -0
  6. data/Appraisals +10 -4
  7. data/Gemfile +8 -1
  8. data/README.md +27 -6
  9. data/Rakefile +17 -0
  10. data/gemfiles/rails_7.gemfile +15 -0
  11. data/gemfiles/rails_7.gemfile.lock +212 -0
  12. data/gemfiles/rails_8.gemfile +15 -0
  13. data/gemfiles/rails_8.gemfile.lock +213 -0
  14. data/gemfiles/rails_8_1.gemfile +15 -0
  15. data/gemfiles/rails_8_1.gemfile.lock +143 -0
  16. data/lib/mongo_trails/callback_propagation.rb +77 -0
  17. data/lib/mongo_trails/config.rb +7 -24
  18. data/lib/mongo_trails/events/base.rb +5 -308
  19. data/lib/mongo_trails/model_config.rb +1 -232
  20. data/lib/mongo_trails/mongo_support/config.rb +7 -1
  21. data/lib/mongo_trails/mongo_support/criteria.rb +7 -0
  22. data/lib/mongo_trails/mongo_support/version.rb +242 -19
  23. data/lib/mongo_trails/mongo_support/version_commit_wrap.rb +37 -0
  24. data/lib/mongo_trails/mongo_support/write_version_worker.rb +11 -0
  25. data/lib/mongo_trails/record_trail.rb +21 -262
  26. data/lib/mongo_trails/version.rb +5 -0
  27. data/lib/mongo_trails/version_concern.rb +4 -293
  28. data/lib/mongo_trails.rb +13 -149
  29. data/mongo_trails.gemspec +19 -20
  30. metadata +50 -85
  31. data/.travis.yml +0 -13
  32. data/Gemfile.lock +0 -62
  33. data/gemfiles/rails_5.gemfile +0 -9
  34. data/gemfiles/rails_5.gemfile.lock +0 -63
  35. data/gemfiles/rails_6.gemfile +0 -9
  36. data/gemfiles/rails_6.gemfile.lock +0 -63
  37. data/lib/mongo_trails/attribute_serializers/README.md +0 -10
  38. data/lib/mongo_trails/attribute_serializers/attribute_serializer_factory.rb +0 -27
  39. data/lib/mongo_trails/attribute_serializers/cast_attribute_serializer.rb +0 -51
  40. data/lib/mongo_trails/attribute_serializers/object_attribute.rb +0 -41
  41. data/lib/mongo_trails/attribute_serializers/object_changes_attribute.rb +0 -44
  42. data/lib/mongo_trails/cleaner.rb +0 -60
  43. data/lib/mongo_trails/compatibility.rb +0 -51
  44. data/lib/mongo_trails/events/create.rb +0 -32
  45. data/lib/mongo_trails/events/destroy.rb +0 -42
  46. data/lib/mongo_trails/events/update.rb +0 -60
  47. data/lib/mongo_trails/frameworks/cucumber.rb +0 -33
  48. data/lib/mongo_trails/frameworks/rails/controller.rb +0 -109
  49. data/lib/mongo_trails/frameworks/rails/engine.rb +0 -43
  50. data/lib/mongo_trails/frameworks/rails.rb +0 -4
  51. data/lib/mongo_trails/frameworks/rspec/helpers.rb +0 -29
  52. data/lib/mongo_trails/frameworks/rspec.rb +0 -43
  53. data/lib/mongo_trails/has_paper_trail.rb +0 -86
  54. data/lib/mongo_trails/queries/versions/where_object.rb +0 -65
  55. data/lib/mongo_trails/queries/versions/where_object_changes.rb +0 -75
  56. data/lib/mongo_trails/record_history.rb +0 -51
  57. data/lib/mongo_trails/reifier.rb +0 -130
  58. data/lib/mongo_trails/request.rb +0 -166
  59. data/lib/mongo_trails/serializers/json.rb +0 -46
  60. data/lib/mongo_trails/serializers/yaml.rb +0 -43
  61. data/lib/mongo_trails/type_serializers/postgres_array_serializer.rb +0 -48
  62. data/lib/mongo_trails/version_number.rb +0 -23
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "mongo_trails/attribute_serializers/object_attribute"
4
- require "mongo_trails/attribute_serializers/object_changes_attribute"
5
- require "mongo_trails/model_config"
6
- require "mongo_trails/record_trail"
7
-
8
- module PaperTrail
9
- # Extensions to `ActiveRecord::Base`. See `frameworks/active_record.rb`.
10
- # It is our goal to have the smallest possible footprint here, because
11
- # `ActiveRecord::Base` is a very crowded namespace! That is why we introduced
12
- # `.paper_trail` and `#paper_trail`.
13
- module Model
14
- def self.included(base)
15
- base.send :extend, ClassMethods
16
- end
17
-
18
- # :nodoc:
19
- module ClassMethods
20
- # Declare this in your model to track every create, update, and destroy.
21
- # Each version of the model is available in the `versions` association.
22
- #
23
- # Options:
24
- #
25
- # - :on - The events to track (optional; defaults to all of them). Set
26
- # to an array of `:create`, `:update`, `:destroy` and `:touch` as desired.
27
- # - :class_name (deprecated) - The name of a custom Version class that
28
- # includes `PaperTrail::VersionConcern`.
29
- # - :ignore - An array of attributes for which a new `Version` will not be
30
- # created if only they change. It can also accept a Hash as an
31
- # argument where the key is the attribute to ignore (a `String` or
32
- # `Symbol`), which will only be ignored if the value is a `Proc` which
33
- # returns truthily.
34
- # - :if, :unless - Procs that allow to specify conditions when to save
35
- # versions for an object.
36
- # - :only - Inverse of `ignore`. A new `Version` will be created only
37
- # for these attributes if supplied it can also accept a Hash as an
38
- # argument where the key is the attribute to track (a `String` or
39
- # `Symbol`), which will only be counted if the value is a `Proc` which
40
- # returns truthily.
41
- # - :skip - Fields to ignore completely. As with `ignore`, updates to
42
- # these fields will not create a new `Version`. In addition, these
43
- # fields will not be included in the serialized versions of the object
44
- # whenever a new `Version` is created.
45
- # - :meta - A hash of extra data to store. You must add a column to the
46
- # `versions` table for each key. Values are objects or procs (which
47
- # are called with `self`, i.e. the model with the paper trail). See
48
- # `PaperTrail::Controller.info_for_paper_trail` for how to store data
49
- # from the controller.
50
- # - :versions - Either,
51
- # - A String (deprecated) - The name to use for the versions
52
- # association. Default is `:versions`.
53
- # - A Hash - options passed to `has_many`, plus `name:` and `scope:`.
54
- # - :version - The name to use for the method which returns the version
55
- # the instance was reified from. Default is `:version`.
56
- #
57
- # Plugins like the experimental `paper_trail-association_tracking` gem
58
- # may accept additional options.
59
- #
60
- # You can define a default set of options via the configurable
61
- # `PaperTrail.config.has_paper_trail_defaults` hash in your applications
62
- # initializer. The hash can contain any of the following options and will
63
- # provide an overridable default for all models.
64
- #
65
- # @api public
66
- def has_paper_trail(options = {})
67
- defaults = PaperTrail.config.has_paper_trail_defaults
68
- paper_trail.setup(defaults.merge(options))
69
- end
70
-
71
- # @api public
72
- def paper_trail
73
- ::PaperTrail::ModelConfig.new(self)
74
- end
75
- end
76
-
77
- # Wrap the following methods in a module so we can include them only in the
78
- # ActiveRecord models that declare `has_paper_trail`.
79
- module InstanceMethods
80
- # @api public
81
- def paper_trail
82
- ::PaperTrail::RecordTrail.new(self)
83
- end
84
- end
85
- end
86
- end
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module PaperTrail
4
- module Queries
5
- module Versions
6
- # For public API documentation, see `where_object` in
7
- # `mongo_trails/version_concern.rb`.
8
- # @api private
9
- class WhereObject
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
- column = @version_model_class.columns_hash["object"]
22
- raise "where_object can't be called without an object column" unless column
23
-
24
- case column.type
25
- when :jsonb
26
- jsonb
27
- when :json
28
- json
29
- else
30
- text
31
- end
32
- end
33
-
34
- private
35
-
36
- # @api private
37
- def json
38
- predicates = []
39
- values = []
40
- @attributes.each do |field, value|
41
- predicates.push "object->>? = ?"
42
- values.concat([field, value.to_s])
43
- end
44
- sql = predicates.join(" and ")
45
- @version_model_class.where(sql, *values)
46
- end
47
-
48
- # @api private
49
- def jsonb
50
- @version_model_class.where("object @> ?", @attributes.to_json)
51
- end
52
-
53
- # @api private
54
- def text
55
- arel_field = @version_model_class.arel_table[:object]
56
- where_conditions = @attributes.map { |field, value|
57
- ::PaperTrail.serializer.where_object_condition(arel_field, field, value)
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
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module PaperTrail
4
- module Queries
5
- module Versions
6
- # For public API documentation, see `where_object_changes` in
7
- # `mongo_trails/version_concern.rb`.
8
- # @api private
9
- class WhereObjectChanges
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
-
17
- # Currently, this `deep_dup` is necessary because the `jsonb` branch
18
- # modifies `@attributes`, and that would be a nasty suprise for
19
- # consumers of this class.
20
- # TODO: Stop modifying `@attributes`, then remove `deep_dup`.
21
- @attributes = attributes.deep_dup
22
- end
23
-
24
- # @api private
25
- def execute
26
- if PaperTrail.config.object_changes_adapter&.respond_to?(:where_object_changes)
27
- return PaperTrail.config.object_changes_adapter.where_object_changes(
28
- @version_model_class, @attributes
29
- )
30
- end
31
- case @version_model_class.columns_hash["object_changes"].type
32
- when :jsonb
33
- jsonb
34
- when :json
35
- json
36
- else
37
- text
38
- end
39
- end
40
-
41
- private
42
-
43
- # @api private
44
- def json
45
- predicates = []
46
- values = []
47
- @attributes.each do |field, value|
48
- predicates.push(
49
- "((object_changes->>? ILIKE ?) OR (object_changes->>? ILIKE ?))"
50
- )
51
- values.concat([field, "[#{value.to_json},%", field, "[%,#{value.to_json}]%"])
52
- end
53
- sql = predicates.join(" and ")
54
- @version_model_class.where(sql, *values)
55
- end
56
-
57
- # @api private
58
- def jsonb
59
- @attributes.each { |field, value| @attributes[field] = [value] }
60
- @version_model_class.where("object_changes @> ?", @attributes.to_json)
61
- 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
- end
73
- end
74
- end
75
- end
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module PaperTrail
4
- # Represents the history of a single record.
5
- # @api private
6
- class RecordHistory
7
- # @param versions - ActiveRecord::Relation - All versions of the record.
8
- # @param version_class - Class - Usually PaperTrail::Version,
9
- # but it could also be a custom version class.
10
- # @api private
11
- def initialize(versions, version_class)
12
- @versions = versions
13
- @version_class = version_class
14
- end
15
-
16
- # Returns ordinal position of `version` in `sequence`.
17
- # @api private
18
- def index(version)
19
- sequence.to_a.index(version)
20
- end
21
-
22
- private
23
-
24
- # Returns `@versions` in chronological order.
25
- # @api private
26
- def sequence
27
- if @version_class.primary_key_is_int?
28
- @versions.select(primary_key).order(primary_key.asc)
29
- else
30
- @versions.
31
- select([table[:created_at], primary_key]).
32
- order(@version_class.timestamp_sort_order)
33
- end
34
- end
35
-
36
- # @return - Arel::Attribute - Attribute representing the primary key
37
- # of the version table. The column's data type is usually a serial
38
- # integer (the rails convention) but not always.
39
- # @api private
40
- def primary_key
41
- table[@version_class.primary_key]
42
- end
43
-
44
- # @return - Arel::Table - The version table, usually named `versions`, but
45
- # not always.
46
- # @api private
47
- def table
48
- @version_class.arel_table
49
- end
50
- end
51
- end
@@ -1,130 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "mongo_trails/attribute_serializers/object_attribute"
4
-
5
- module PaperTrail
6
- # Given a version record and some options, builds a new model object.
7
- # @api private
8
- module Reifier
9
- class << self
10
- # See `VersionConcern#reify` for documentation.
11
- # @api private
12
- def reify(version, options)
13
- options = apply_defaults_to(options, version)
14
- attrs = version.object_deserialized
15
- model = init_model(attrs, options, version)
16
- reify_attributes(model, version, attrs)
17
- model.send "#{model.class.version_association_name}=", version
18
- model
19
- end
20
-
21
- private
22
-
23
- # Given a hash of `options` for `.reify`, return a new hash with default
24
- # values applied.
25
- # @api private
26
- def apply_defaults_to(options, version)
27
- {
28
- version_at: version.created_at,
29
- mark_for_destruction: false,
30
- has_one: false,
31
- has_many: false,
32
- belongs_to: false,
33
- has_and_belongs_to_many: false,
34
- unversioned_attributes: :nil
35
- }.merge(options)
36
- end
37
-
38
- # Initialize a model object suitable for reifying `version` into. Does
39
- # not perform reification, merely instantiates the appropriate model
40
- # class and, if specified by `options[:unversioned_attributes]`, sets
41
- # unversioned attributes to `nil`.
42
- #
43
- # Normally a polymorphic belongs_to relationship allows us to get the
44
- # object we belong to by calling, in this case, `item`. However this
45
- # returns nil if `item` has been destroyed, and we need to be able to
46
- # retrieve destroyed objects.
47
- #
48
- # In this situation we constantize the `item_type` to get hold of the
49
- # class...except when the stored object's attributes include a `type`
50
- # key. If this is the case, the object we belong to is using single
51
- # table inheritance (STI) and the `item_type` will be the base class,
52
- # not the actual subclass. If `type` is present but empty, the class is
53
- # the base class.
54
- def init_model(attrs, options, version)
55
- klass = version_reification_class(version, attrs)
56
-
57
- # The `dup` option and destroyed version always returns a new object,
58
- # otherwise we should attempt to load item or to look for the item
59
- # outside of default scope(s).
60
- model = if options[:dup] == true || version.event == "destroy"
61
- klass.new
62
- else
63
- find_cond = { klass.primary_key => version.item_id }
64
-
65
- version.item || klass.unscoped.where(find_cond).first || klass.new
66
- end
67
-
68
- if options[:unversioned_attributes] == :nil && !model.new_record?
69
- init_unversioned_attrs(attrs, model)
70
- end
71
-
72
- model
73
- end
74
-
75
- # Look for attributes that exist in `model` and not in this version.
76
- # These attributes should be set to nil. Modifies `attrs`.
77
- # @api private
78
- def init_unversioned_attrs(attrs, model)
79
- (model.attribute_names - attrs.keys).each { |k| attrs[k] = nil }
80
- end
81
-
82
- # Reify onto `model` an attribute named `k` with value `v` from `version`.
83
- #
84
- # `ObjectAttribute#deserialize` will return the mapped enum value and in
85
- # Rails < 5, the []= uses the integer type caster from the column
86
- # definition (in general) and thus will turn a (usually) string to 0
87
- # instead of the correct value.
88
- #
89
- # @api private
90
- def reify_attribute(k, v, model, version)
91
- if model.has_attribute?(k)
92
- model[k.to_sym] = v
93
- elsif model.respond_to?("#{k}=")
94
- model.send("#{k}=", v)
95
- elsif version.logger
96
- version.logger.warn(
97
- "Attribute #{k} does not exist on #{version.item_type} (Version id: #{version.id})."
98
- )
99
- end
100
- end
101
-
102
- # Reify onto `model` all the attributes of `version`.
103
- # @api private
104
- def reify_attributes(model, version, attrs)
105
- AttributeSerializers::ObjectAttribute.new(model.class).deserialize(attrs)
106
- attrs.each do |k, v|
107
- reify_attribute(k, v, model, version)
108
- end
109
- end
110
-
111
- # Given a `version`, return the class to reify. This method supports
112
- # Single Table Inheritance (STI) with custom inheritance columns.
113
- #
114
- # For example, imagine a `version` whose `item_type` is "Animal". The
115
- # `animals` table is an STI table (it has cats and dogs) and it has a
116
- # custom inheritance column, `species`. If `attrs["species"]` is "Dog",
117
- # 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`.
120
- #
121
- # TODO: Duplication: similar `constantize` in VersionConcern#version_limit
122
- def version_reification_class(version, attrs)
123
- inheritance_column_name = version.item_type.constantize.inheritance_column
124
- inher_col_value = attrs[inheritance_column_name]
125
- class_name = inher_col_value.blank? ? version.item_type : inher_col_value
126
- class_name.constantize
127
- end
128
- end
129
- end
130
- end
@@ -1,166 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "request_store"
4
-
5
- module PaperTrail
6
- # Manages variables that affect the current HTTP request, such as `whodunnit`.
7
- #
8
- # Please do not use `PaperTrail::Request` directly, use `PaperTrail.request`.
9
- # Currently, `Request` is a `Module`, but in the future it is quite possible
10
- # we may make it a `Class`. If we make such a choice, we will not provide any
11
- # warning and will not treat it as a breaking change. You've been warned :)
12
- #
13
- # @api private
14
- module Request
15
- class InvalidOption < RuntimeError
16
- end
17
-
18
- class << self
19
- # Sets any data from the controller that you want PaperTrail to store.
20
- # See also `PaperTrail::Rails::Controller#info_for_paper_trail`.
21
- #
22
- # PaperTrail.request.controller_info = { ip: request_user_ip }
23
- # PaperTrail.request.controller_info # => { ip: '127.0.0.1' }
24
- #
25
- # @api public
26
- def controller_info=(value)
27
- store[:controller_info] = value
28
- end
29
-
30
- # Returns the data from the controller that you want PaperTrail to store.
31
- # See also `PaperTrail::Rails::Controller#info_for_paper_trail`.
32
- #
33
- # PaperTrail.request.controller_info = { ip: request_user_ip }
34
- # PaperTrail.request.controller_info # => { ip: '127.0.0.1' }
35
- #
36
- # @api public
37
- def controller_info
38
- store[:controller_info]
39
- end
40
-
41
- # Switches PaperTrail off for the given model.
42
- # @api public
43
- def disable_model(model_class)
44
- enabled_for_model(model_class, false)
45
- end
46
-
47
- # Switches PaperTrail on for the given model.
48
- # @api public
49
- def enable_model(model_class)
50
- enabled_for_model(model_class, true)
51
- end
52
-
53
- # Sets whether PaperTrail is enabled or disabled for the current request.
54
- # @api public
55
- def enabled=(value)
56
- store[:enabled] = value
57
- end
58
-
59
- # Returns `true` if PaperTrail is enabled for the request, `false` otherwise.
60
- # See `PaperTrail::Rails::Controller#paper_trail_enabled_for_controller`.
61
- # @api public
62
- def enabled?
63
- !!store[:enabled]
64
- end
65
-
66
- # Sets whether PaperTrail is enabled or disabled for this model in the
67
- # current request.
68
- # @api public
69
- def enabled_for_model(model, value)
70
- store[:"enabled_for_#{model}"] = value
71
- end
72
-
73
- # Returns `true` if PaperTrail is enabled for this model in the current
74
- # request, `false` otherwise.
75
- # @api public
76
- def enabled_for_model?(model)
77
- model.include?(::PaperTrail::Model::InstanceMethods) &&
78
- !!store.fetch(:"enabled_for_#{model}", true)
79
- end
80
-
81
- # @api private
82
- def merge(options)
83
- options.to_h.each do |k, v|
84
- store[k] = v
85
- end
86
- end
87
-
88
- # @api private
89
- def set(options)
90
- store.clear
91
- merge(options)
92
- end
93
-
94
- # Returns a deep copy of the internal hash from our RequestStore. Keys are
95
- # all symbols. Values are mostly primitives, but whodunnit can be a Proc.
96
- # We cannot use Marshal.dump here because it doesn't support Proc. It is
97
- # unclear exactly how `deep_dup` handles a Proc, but it doesn't complain.
98
- # @api private
99
- def to_h
100
- store.deep_dup
101
- end
102
-
103
- # Temporarily set `options` and execute a block.
104
- # @api private
105
- def with(options)
106
- return unless block_given?
107
- validate_public_options(options)
108
- before = to_h
109
- merge(options)
110
- yield
111
- ensure
112
- set(before)
113
- end
114
-
115
- # Sets who is responsible for any changes that occur during request. You
116
- # would normally use this in a migration or on the console, when working
117
- # with models directly.
118
- #
119
- # `value` is usually a string, the name of a person, but you can set
120
- # anything that responds to `to_s`. You can also set a Proc, which will
121
- # not be evaluated until `whodunnit` is called later, usually right before
122
- # inserting a `Version` record.
123
- #
124
- # @api public
125
- def whodunnit=(value)
126
- store[:whodunnit] = value
127
- end
128
-
129
- # Returns who is reponsible for any changes that occur during request.
130
- #
131
- # @api public
132
- def whodunnit
133
- who = store[:whodunnit]
134
- who.respond_to?(:call) ? who.call : who
135
- end
136
-
137
- private
138
-
139
- # Returns a Hash, initializing with default values if necessary.
140
- # @api private
141
- def store
142
- RequestStore.store[:paper_trail] ||= {
143
- enabled: true
144
- }
145
- end
146
-
147
- # Provide a helpful error message if someone has a typo in one of their
148
- # option keys. We don't validate option values here. That's traditionally
149
- # been handled with casting (`to_s`, `!!`) in the accessor method.
150
- # @api private
151
- def validate_public_options(options)
152
- options.each do |k, _v|
153
- case k
154
- when :controller_info,
155
- /enabled_for_/,
156
- :enabled,
157
- :whodunnit
158
- next
159
- else
160
- raise InvalidOption, "Invalid option: #{k}"
161
- end
162
- end
163
- end
164
- end
165
- end
166
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module PaperTrail
4
- module Serializers
5
- # An alternate serializer for, e.g. `versions.object`.
6
- module JSON
7
- extend self # makes all instance methods become module methods as well
8
-
9
- def load(string)
10
- ActiveSupport::JSON.decode string
11
- end
12
-
13
- def dump(object)
14
- ActiveSupport::JSON.encode object
15
- end
16
-
17
- # Returns a SQL LIKE condition to be used to match the given field and
18
- # value in the serialized object.
19
- def where_object_condition(arel_field, field, value)
20
- # Convert to JSON to handle strings and nulls correctly.
21
- json_value = value.to_json
22
-
23
- # If the value is a number, we need to ensure that we find the next
24
- # character too, which is either `,` or `}`, to ensure that searching
25
- # for the value 12 doesn't yield false positives when the value is
26
- # 123.
27
- if value.is_a? Numeric
28
- arel_field.matches("%\"#{field}\":#{json_value},%").
29
- or(arel_field.matches("%\"#{field}\":#{json_value}}%"))
30
- else
31
- arel_field.matches("%\"#{field}\":#{json_value}%")
32
- end
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
- end
45
- end
46
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "yaml"
4
-
5
- module PaperTrail
6
- module Serializers
7
- # The default serializer for, e.g. `versions.object`.
8
- module YAML
9
- extend self # makes all instance methods become module methods as well
10
-
11
- def load(string)
12
- ::YAML.load string
13
- end
14
-
15
- # @param object (Hash | HashWithIndifferentAccess) - Coming from
16
- # `recordable_object` `object` will be a plain `Hash`. However, due to
17
- # recent [memory optimizations](https://git.io/fjeYv), when coming from
18
- # `recordable_object_changes`, it will be a `HashWithIndifferentAccess`.
19
- def dump(object)
20
- object = object.to_hash if object.is_a?(HashWithIndifferentAccess)
21
- ::YAML.dump object
22
- end
23
-
24
- # Returns a SQL LIKE condition to be used to match the given field and
25
- # value in the serialized object.
26
- def where_object_condition(arel_field, field, value)
27
- arel_field.matches("%\n#{field}: #{value}\n%")
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
- end
42
- end
43
- end