mongoid 9.0.8 → 9.0.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '032258516f15736f4121de82ee4cdcdb625515f653f85a66b0df613665236e4d'
4
- data.tar.gz: 443ec24d9a54bb10c87023cd6304081aa48bf92bf5654044cc935f79ca954b9c
3
+ metadata.gz: fefd49681b6f78b222f201fbaea83af9f1599464034e52a73117c0ae94e201f2
4
+ data.tar.gz: d86f966109921d2a0f1a4ce0b78d81e0d722123c1d420f0f695385ca43687626
5
5
  SHA512:
6
- metadata.gz: 3c875bf631d019da208fa59221a74e3468931a802664e43ce2e8ed669e990722a499d8976a8acafb8078dbeff8c02a76df96b9d76f8e33c0c979658f40748fd9
7
- data.tar.gz: 46943ea7b081db4784159bacc2056b75b6511f8c8892910dc2c2bfc7ee1229a6ddf0d9141f52137a12a04eea841c24e16b4eae7fb8fc15bd26e2dec7d0273ecc
6
+ metadata.gz: '09799846ca2a44c7dc4d7aff76fba0f9fdcbe38c5bfb001dccd08eb467800f8fac675cecfa06be94eb76ca35f6f1b57b64557ed171e9c0040bcbe0a701d7827f'
7
+ data.tar.gz: bc0a741e2e26a84e84238f1461a26a29ae13584d9bd050dffc1ccd04f70e4e6a7fa63b20e7dcda8137ce3c37d383a5ae916b0d72ff950d4f330e66e0635ea89c
@@ -14,6 +14,7 @@ module Mongoid
14
14
  # the array of child documents.
15
15
  class Proxy < Association::Many
16
16
  include Batchable
17
+ extend Forwardable
17
18
 
18
19
  # Class-level methods for the Proxy class.
19
20
  module ClassMethods
@@ -54,6 +55,8 @@ module Mongoid
54
55
 
55
56
  extend ClassMethods
56
57
 
58
+ def_delegators :criteria, :find, :pluck
59
+
57
60
  # Instantiate a new embeds_many association.
58
61
  #
59
62
  # @example Create the new association.
@@ -312,35 +315,6 @@ module Mongoid
312
315
  end
313
316
  end
314
317
 
315
- # Finds a document in this association through several different
316
- # methods.
317
- #
318
- # This method delegates to +Mongoid::Criteria#find+. If this method is
319
- # not given a block, it returns one or many documents for the provided
320
- # _id values.
321
- #
322
- # If this method is given a block, it returns the first document
323
- # of those found by the current Criteria object for which the block
324
- # returns a truthy value.
325
- #
326
- # @example Find a document by its id.
327
- # person.addresses.find(BSON::ObjectId.new)
328
- #
329
- # @example Find documents for multiple ids.
330
- # person.addresses.find([ BSON::ObjectId.new, BSON::ObjectId.new ])
331
- #
332
- # @example Finds the first matching document using a block.
333
- # person.addresses.find { |addr| addr.state == 'CA' }
334
- #
335
- # @param [ Object... ] *args Various arguments.
336
- # @param &block Optional block to pass.
337
- # @yield [ Object ] Yields each enumerable element to the block.
338
- #
339
- # @return [ Document | Array<Document> | nil ] A document or matching documents.
340
- def find(...)
341
- criteria.find(...)
342
- end
343
-
344
318
  # Get all the documents in the association that are loaded into memory.
345
319
  #
346
320
  # @example Get the in memory documents.
@@ -53,8 +53,6 @@ module Mongoid
53
53
  # @param [ Document... ] *args Any number of documents.
54
54
  #
55
55
  # @return [ Array<Document> ] The loaded docs.
56
- #
57
- # rubocop:disable Metrics/AbcSize
58
56
  def <<(*args)
59
57
  docs = args.flatten
60
58
  return concat(docs) if docs.size > 1
@@ -89,7 +87,6 @@ module Mongoid
89
87
  end
90
88
  unsynced(_base, foreign_key) and self
91
89
  end
92
- # rubocop:enable Metrics/AbcSize
93
90
 
94
91
  alias push <<
95
92
 
@@ -360,8 +357,6 @@ module Mongoid
360
357
  # in bulk
361
358
  # @param [ Array ] inserts the list of Hashes of attributes that will
362
359
  # be inserted (corresponding to the ``docs`` list)
363
- #
364
- # rubocop:disable Metrics/AbcSize
365
360
  def append_document(doc, ids, docs, inserts)
366
361
  return unless doc
367
362
 
@@ -379,7 +374,6 @@ module Mongoid
379
374
  unsynced(_base, foreign_key)
380
375
  end
381
376
  end
382
- # rubocop:enable Metrics/AbcSize
383
377
  end
384
378
  end
385
379
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
  # rubocop:todo all
3
3
 
4
+ require 'mongoid/pluckable'
5
+
4
6
  module Mongoid
5
7
  module Association
6
8
  module Referenced
@@ -12,6 +14,7 @@ module Mongoid
12
14
  class Enumerable
13
15
  extend Forwardable
14
16
  include ::Enumerable
17
+ include Pluckable
15
18
 
16
19
  # The three main instance variables are collections of documents.
17
20
  #
@@ -374,6 +377,43 @@ module Mongoid
374
377
  @_added, @_loaded, @_unloaded, @executed = data
375
378
  end
376
379
 
380
+ # Plucks the given field names from the documents in the target.
381
+ # If the collection has been loaded, it plucks from the loaded
382
+ # documents; otherwise, it plucks from the unloaded criteria.
383
+ # Regardless, it also plucks from any added documents.
384
+ #
385
+ # @param [ Symbol... ] *fields The field names to pluck.
386
+ #
387
+ # @return [ Array | Array<Array> ] The array of field values. If
388
+ # multiple fields are given, an array of arrays is returned.
389
+ def pluck(*keys)
390
+ [].tap do |results|
391
+ if _loaded? || _added.any?
392
+ klass = @_association.klass
393
+ prepared = prepare_pluck(keys, document_class: klass)
394
+ end
395
+
396
+ if _loaded?
397
+ docs = _loaded.values.map { |v| BSON::Document.new(v.attributes) }
398
+ results.concat pluck_from_documents(docs, prepared[:field_names], document_class: klass)
399
+ elsif _unloaded
400
+ criteria = if _added.any?
401
+ ids_to_exclude = _added.keys
402
+ _unloaded.not(:_id.in => ids_to_exclude)
403
+ else
404
+ _unloaded
405
+ end
406
+
407
+ results.concat criteria.pluck(*keys)
408
+ end
409
+
410
+ if _added.any?
411
+ docs = _added.values.map { |v| BSON::Document.new(v.attributes) }
412
+ results.concat pluck_from_documents(docs, prepared[:field_names], document_class: klass)
413
+ end
414
+ end
415
+ end
416
+
377
417
  # Reset the enumerable back to its persisted state.
378
418
  #
379
419
  # @example Reset the enumerable.
@@ -33,7 +33,7 @@ module Mongoid
33
33
 
34
34
  extend ClassMethods
35
35
 
36
- def_delegator :criteria, :count
36
+ def_delegators :criteria, :count
37
37
  def_delegators :_target, :first, :in_memory, :last, :reset, :uniq
38
38
 
39
39
  # Instantiate a new references_many association. Will set the foreign key
@@ -281,6 +281,22 @@ module Mongoid
281
281
 
282
282
  alias nullify_all nullify
283
283
 
284
+ # Plucks the given field names from the documents in the
285
+ # association. It is safe to use whether the association is
286
+ # loaded or not, and whether there are unsaved documents in the
287
+ # association or not.
288
+ #
289
+ # @example Pluck the titles of all posts.
290
+ # person.posts.pluck(:title)
291
+ #
292
+ # @param [ Symbol... ] *fields The field names to pluck.
293
+ #
294
+ # @return [ Array | Array<Array> ] The array of field values. If
295
+ # multiple fields are given, an array of arrays is returned.
296
+ def pluck(*fields)
297
+ _target.pluck(*fields)
298
+ end
299
+
284
300
  # Clear the association. Will delete the documents from the db if they are
285
301
  # already persisted.
286
302
  #
@@ -104,7 +104,8 @@ module Mongoid
104
104
  # @api private
105
105
  def process_raw_attribute(name, raw, field)
106
106
  value = field ? field.demongoize(raw) : raw
107
- attribute_will_change!(name) if value.resizable?
107
+ is_relation = relations.key?(name)
108
+ attribute_will_change!(name) if value.resizable? && !is_relation
108
109
  value
109
110
  end
110
111
 
@@ -175,7 +176,7 @@ module Mongoid
175
176
  localized = fields[field_name].try(:localized?)
176
177
  attributes_before_type_cast[name.to_s] = value
177
178
  typed_value = typed_value_for(field_name, value)
178
- unless attributes[field_name] == typed_value || attribute_changed?(field_name)
179
+ unless attribute_will_not_change?(field_name, typed_value) || attribute_changed?(field_name)
179
180
  attribute_will_change!(field_name)
180
181
  end
181
182
  if localized
@@ -366,5 +367,23 @@ module Mongoid
366
367
  end
367
368
  value.present?
368
369
  end
370
+
371
+ # If `value` is a `BSON::Decimal128`, convert it to a `BigDecimal` for
372
+ # comparison purposes. This is necessary because `BSON::Decimal128` does
373
+ # not implement `#==` in a way that is compatible with `BigDecimal`.
374
+ def normalize_value(value)
375
+ value.is_a?(BSON::Decimal128) ? BigDecimal(value.to_s) : value
376
+ end
377
+
378
+ # Determine if the attribute will not change, by comparing the current
379
+ # value with the new value. The values are normalized to account for
380
+ # types that do not implement `#==` in a way that is compatible with
381
+ # each other, such as `BSON::Decimal128` and `BigDecimal`.
382
+ def attribute_will_not_change?(field_name, typed_value)
383
+ normalized_attribute = normalize_value(attributes[field_name])
384
+ normalized_typed_value = normalize_value(typed_value)
385
+
386
+ normalized_attribute == normalized_typed_value
387
+ end
369
388
  end
370
389
  end
@@ -131,6 +131,10 @@ module Mongoid
131
131
  [MONGOID_WRAPPING_LIBRARY] + options[:wrapping_libraries]
132
132
  else
133
133
  [MONGOID_WRAPPING_LIBRARY]
134
+ end.tap do |wrap|
135
+ if defined?(::Rails) && ::Rails.respond_to?(:version)
136
+ wrap << { name: 'Rails', version: ::Rails.version }
137
+ end
134
138
  end
135
139
  options[:wrapping_libraries] = wrap_lib
136
140
  end
@@ -2,6 +2,7 @@
2
2
  # rubocop:todo all
3
3
 
4
4
  require 'mongoid/atomic_update_preparer'
5
+ require 'mongoid/pluckable'
5
6
  require "mongoid/contextual/mongo/documents_loader"
6
7
  require "mongoid/contextual/atomic"
7
8
  require "mongoid/contextual/aggregable/mongo"
@@ -22,6 +23,7 @@ module Mongoid
22
23
  include Atomic
23
24
  include Association::EagerLoadable
24
25
  include Queryable
26
+ include Pluckable
25
27
 
26
28
  # Options constant.
27
29
  OPTIONS = [ :hint,
@@ -331,23 +333,12 @@ module Mongoid
331
333
  # in the array will be a single value. Otherwise, each
332
334
  # result in the array will be an array of values.
333
335
  def pluck(*fields)
334
- # Multiple fields can map to the same field name. For example, plucking
335
- # a field and its _translations field map to the same field in the database.
336
- # because of this, we need to keep track of the fields requested.
337
- normalized_field_names = []
338
- normalized_select = fields.inject({}) do |hash, f|
339
- db_fn = klass.database_field_name(f)
340
- normalized_field_names.push(db_fn)
341
- hash[klass.cleanse_localized_field_names(f)] = true
342
- hash
343
- end
344
-
345
- view.projection(normalized_select).reduce([]) do |plucked, doc|
346
- values = normalized_field_names.map do |n|
347
- extract_value(doc, n)
348
- end
349
- plucked << (values.size == 1 ? values.first : values)
350
- end
336
+ # Multiple fields can map to the same field name. For example,
337
+ # plucking a field and its _translations field map to the same
338
+ # field in the database. because of this, we need to prepare the
339
+ # projection specifically.
340
+ prep = prepare_pluck(fields, prepare_projection: true)
341
+ pluck_from_documents(view.projection(prep[:projection]), prep[:field_names])
351
342
  end
352
343
 
353
344
  # Pick the single field values from the database.
@@ -893,78 +884,6 @@ module Mongoid
893
884
  collection.write_concern.nil? || collection.write_concern.acknowledged?
894
885
  end
895
886
 
896
- # Fetch the element from the given hash and demongoize it using the
897
- # given field. If the obj is an array, map over it and call this method
898
- # on all of its elements.
899
- #
900
- # @param [ Hash | Array<Hash> ] obj The hash or array of hashes to fetch from.
901
- # @param [ String ] meth The key to fetch from the hash.
902
- # @param [ Field ] field The field to use for demongoization.
903
- #
904
- # @return [ Object ] The demongoized value.
905
- #
906
- # @api private
907
- def fetch_and_demongoize(obj, meth, field)
908
- if obj.is_a?(Array)
909
- obj.map { |doc| fetch_and_demongoize(doc, meth, field) }
910
- else
911
- res = obj.try(:fetch, meth, nil)
912
- field ? field.demongoize(res) : res.class.demongoize(res)
913
- end
914
- end
915
-
916
- # Extracts the value for the given field name from the given attribute
917
- # hash.
918
- #
919
- # @param [ Hash ] attrs The attributes hash.
920
- # @param [ String ] field_name The name of the field to extract.
921
- #
922
- # @param [ Object ] The value for the given field name
923
- def extract_value(attrs, field_name)
924
- i = 1
925
- num_meths = field_name.count('.') + 1
926
- curr = attrs.dup
927
-
928
- klass.traverse_association_tree(field_name) do |meth, obj, is_field|
929
- field = obj if is_field
930
- is_translation = false
931
- # If no association or field was found, check if the meth is an
932
- # _translations field.
933
- if obj.nil? & tr = meth.match(/(.*)_translations\z/)&.captures&.first
934
- is_translation = true
935
- meth = tr
936
- end
937
-
938
- # 1. If curr is an array fetch from all elements in the array.
939
- # 2. If the field is localized, and is not an _translations field
940
- # (_translations fields don't show up in the fields hash).
941
- # - If this is the end of the methods, return the translation for
942
- # the current locale.
943
- # - Otherwise, return the whole translations hash so the next method
944
- # can select the language it wants.
945
- # 3. If the meth is an _translations field, do not demongoize the
946
- # value so the full hash is returned.
947
- # 4. Otherwise, fetch and demongoize the value for the key meth.
948
- curr = if curr.is_a? Array
949
- res = fetch_and_demongoize(curr, meth, field)
950
- res.empty? ? nil : res
951
- elsif !is_translation && field&.localized?
952
- if i < num_meths
953
- curr.try(:fetch, meth, nil)
954
- else
955
- fetch_and_demongoize(curr, meth, field)
956
- end
957
- elsif is_translation
958
- curr.try(:fetch, meth, nil)
959
- else
960
- fetch_and_demongoize(curr, meth, field)
961
- end
962
-
963
- i += 1
964
- end
965
- curr
966
- end
967
-
968
887
  # Recursively demongoize the given value. This method recursively traverses
969
888
  # the class tree to find the correct field to use to demongoize the value.
970
889
  #
@@ -41,24 +41,57 @@ module Mongoid
41
41
  include Clients::Sessions
42
42
  include Options
43
43
 
44
+ # Allowed methods for from_hash to prevent arbitrary method execution.
45
+ # Only query-building methods are allowed, not execution or modification methods.
46
+ ALLOWED_FROM_HASH_METHODS = %i[
47
+ all all_in all_of and any_in any_of asc ascending
48
+ batch_size between
49
+ collation comment cursor_type
50
+ desc descending
51
+ elem_match eq exists extras
52
+ geo_spatial group gt gte
53
+ hint
54
+ in includes
55
+ limit lt lte
56
+ max_distance max_scan max_time_ms merge mod
57
+ ne near near_sphere nin no_timeout none none_of nor not not_in
58
+ offset only or order order_by
59
+ project
60
+ raw read reorder
61
+ scoped skip slice snapshot
62
+ text_search type
63
+ unscoped unwind
64
+ where with_size with_type without
65
+ ].freeze
66
+
44
67
  class << self
45
68
  # Convert the given hash to a criteria. Will iterate over each keys in the
46
- # hash which must correspond to method on a criteria object. The hash
47
- # must also include a "klass" key.
69
+ # hash which must correspond to an allowed method on a criteria object. The hash
70
+ # can include a "klass" key that specifies the model class for the criteria.
48
71
  #
49
72
  # @example Convert the hash to a criteria.
50
73
  # Criteria.from_hash({ klass: Band, where: { name: "Depeche Mode" })
51
74
  #
75
+ # @deprecated This method is deprecated and will
76
+ # be removed in a future release.
77
+ #
52
78
  # @param [ Hash ] hash The hash to convert.
53
79
  #
54
80
  # @return [ Criteria ] The criteria.
81
+ #
82
+ # @raise [ ArgumentError ] If a method is not allowed in from_hash.
55
83
  def from_hash(hash)
56
84
  criteria = Criteria.new(hash.delete(:klass) || hash.delete('klass'))
57
85
  hash.each_pair do |method, args|
58
- criteria = criteria.__send__(method, args)
86
+ method_sym = method.to_sym
87
+ unless ALLOWED_FROM_HASH_METHODS.include?(method_sym)
88
+ raise ArgumentError, "Method '#{method}' is not allowed in from_hash"
89
+ end
90
+ criteria = criteria.public_send(method_sym, args)
59
91
  end
60
92
  criteria
61
93
  end
94
+ Mongoid.deprecate(self, :from_hash)
62
95
  end
63
96
 
64
97
  # Static array used to check with method missing - we only need to ever
@@ -246,7 +279,8 @@ module Mongoid
246
279
  # criteria.merge(other_criteria)
247
280
  #
248
281
  # @example Merge the criteria with a hash. The hash must contain a klass
249
- # key and the key/value pairs correspond to method names/args.
282
+ # key that specifies the model class for the criteria and the key/value
283
+ # pairs correspond to method names/args.
250
284
  #
251
285
  # criteria.merge({
252
286
  # klass: Band,
@@ -254,7 +288,7 @@ module Mongoid
254
288
  # order_by: { name: 1 }
255
289
  # })
256
290
  #
257
- # @param [ Criteria ] other The other criterion to merge with.
291
+ # @param [ Criteria | Hash ] other The other criterion to merge with.
258
292
  #
259
293
  # @return [ Criteria ] A cloned self.
260
294
  def merge(other)
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongoid
4
+ # Provides shared behavior for any document with "pluck" functionality.
5
+ #
6
+ # @api private
7
+ module Pluckable
8
+ extend ActiveSupport::Concern
9
+
10
+ private
11
+
12
+ # Prepares the field names for plucking by normalizing them to their
13
+ # database field names. Also prepares a projection hash if requested.
14
+ def prepare_pluck(field_names, document_class: klass, prepare_projection: false)
15
+ normalized_field_names = []
16
+ projection = {}
17
+
18
+ field_names.each do |f|
19
+ db_fn = document_class.database_field_name(f)
20
+ normalized_field_names.push(db_fn)
21
+
22
+ next unless prepare_projection
23
+
24
+ cleaned_name = document_class.cleanse_localized_field_names(f)
25
+ canonical_name = document_class.database_field_name(cleaned_name)
26
+ projection[canonical_name] = true
27
+ end
28
+
29
+ { field_names: normalized_field_names, projection: projection }
30
+ end
31
+
32
+ # Plucks the given field names from the given documents.
33
+ def pluck_from_documents(documents, field_names, document_class: klass)
34
+ documents.reduce([]) do |plucked, doc|
35
+ values = field_names.map { |name| extract_value(doc, name.to_s, document_class) }
36
+ plucked << ((values.size == 1) ? values.first : values)
37
+ end
38
+ end
39
+
40
+ # Fetch the element from the given hash and demongoize it using the
41
+ # given field. If the obj is an array, map over it and call this method
42
+ # on all of its elements.
43
+ #
44
+ # @param [ Hash | Array<Hash> ] obj The hash or array of hashes to fetch from.
45
+ # @param [ String ] key The key to fetch from the hash.
46
+ # @param [ Field ] field The field to use for demongoization.
47
+ #
48
+ # @return [ Object ] The demongoized value.
49
+ def fetch_and_demongoize(obj, key, field)
50
+ if obj.is_a?(Array)
51
+ obj.map { |doc| fetch_and_demongoize(doc, key, field) }
52
+ else
53
+ value = obj.try(:fetch, key, nil)
54
+ field ? field.demongoize(value) : value.class.demongoize(value)
55
+ end
56
+ end
57
+
58
+ # Extracts the value for the given field name from the given attribute
59
+ # hash.
60
+ #
61
+ # @param [ Hash ] attrs The attributes hash.
62
+ # @param [ String ] field_name The name of the field to extract.
63
+ #
64
+ # @return [ Object ] The value for the given field name
65
+ def extract_value(attrs, field_name, document_class)
66
+ i = 1
67
+ num_meths = field_name.count('.') + 1
68
+ curr = attrs.dup
69
+
70
+ document_class.traverse_association_tree(field_name) do |meth, obj, is_field|
71
+ field = obj if is_field
72
+
73
+ # use the correct document class to check for localized fields on
74
+ # embedded documents.
75
+ document_class = obj.klass if obj.respond_to?(:klass)
76
+
77
+ is_translation = false
78
+ # If no association or field was found, check if the meth is an
79
+ # _translations field.
80
+ if obj.nil? && (tr = meth.match(/(.*)_translations\z/)&.captures&.first)
81
+ is_translation = true
82
+ meth = document_class.database_field_name(tr)
83
+ end
84
+
85
+ curr = descend(i, curr, meth, field, num_meths, is_translation)
86
+
87
+ i += 1
88
+ end
89
+ curr
90
+ end
91
+
92
+ # Descend one level in the attribute hash.
93
+ #
94
+ # @param [ Integer ] part The current part index.
95
+ # @param [ Hash | Array<Hash> ] current The current level in the attribute hash.
96
+ # @param [ String ] method_name The method name to descend to.
97
+ # @param [ Field|nil ] field The field to use for demongoization.
98
+ # @param [ Boolean ] is_translation Whether the method is an _translations field.
99
+ # @param [ Integer ] part_count The total number of parts in the field name.
100
+ #
101
+ # @return [ Object ] The value at the next level.
102
+ #
103
+ # rubocop:disable Metrics/ParameterLists
104
+ def descend(part, current, method_name, field, part_count, is_translation)
105
+ # 1. If curr is an array fetch from all elements in the array.
106
+ # 2. If the field is localized, and is not an _translations field
107
+ # (_translations fields don't show up in the fields hash).
108
+ # - If this is the end of the methods, return the translation for
109
+ # the current locale.
110
+ # - Otherwise, return the whole translations hash so the next method
111
+ # can select the language it wants.
112
+ # 3. If the meth is an _translations field, do not demongoize the
113
+ # value so the full hash is returned.
114
+ # 4. Otherwise, fetch and demongoize the value for the key meth.
115
+ if current.is_a? Array
116
+ res = fetch_and_demongoize(current, method_name, field)
117
+ res.empty? ? nil : res
118
+ elsif !is_translation && field&.localized?
119
+ if part < part_count
120
+ current.try(:fetch, method_name, nil)
121
+ else
122
+ fetch_and_demongoize(current, method_name, field)
123
+ end
124
+ elsif is_translation
125
+ current.try(:fetch, method_name, nil)
126
+ else
127
+ fetch_and_demongoize(current, method_name, field)
128
+ end
129
+ end
130
+ # rubocop:enable Metrics/ParameterLists
131
+ end
132
+ end
@@ -131,7 +131,6 @@ module Mongoid
131
131
  # @param [ String ] value The discriminator key to set.
132
132
  #
133
133
  # @api private
134
- # rubocop:disable Metrics/AbcSize
135
134
  def discriminator_key=(value)
136
135
  raise Errors::InvalidDiscriminatorKeyTarget.new(self, superclass) if hereditary?
137
136
 
@@ -159,7 +158,6 @@ module Mongoid
159
158
  default_proc = -> { self.class.discriminator_value }
160
159
  field(discriminator_key, default: default_proc, type: String)
161
160
  end
162
- # rubocop:enable Metrics/AbcSize
163
161
 
164
162
  # Returns the discriminator key.
165
163
  #
@@ -5,5 +5,5 @@ module Mongoid
5
5
  #
6
6
  # Note that this file is automatically updated via `rake candidate:create`.
7
7
  # Manual changes to this file will be overwritten by that rake task.
8
- VERSION = '9.0.8'
8
+ VERSION = '9.0.10'
9
9
  end