mongoid 7.4.0 → 8.0.1
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
- checksums.yaml.gz.sig +0 -0
- data/README.md +3 -3
- data/lib/config/locales/en.yml +51 -28
- data/lib/mongoid/association/accessors.rb +32 -3
- data/lib/mongoid/association/bindable.rb +48 -0
- data/lib/mongoid/association/builders.rb +4 -2
- data/lib/mongoid/association/eager_loadable.rb +29 -7
- data/lib/mongoid/association/embedded/batchable.rb +48 -8
- data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
- data/lib/mongoid/association/embedded/embedded_in.rb +2 -1
- data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +40 -18
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +21 -2
- data/lib/mongoid/association/macros.rb +22 -1
- data/lib/mongoid/association/many.rb +5 -0
- data/lib/mongoid/association/nested/many.rb +2 -1
- data/lib/mongoid/association/proxy.rb +12 -0
- data/lib/mongoid/association/referenced/auto_save.rb +3 -2
- data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
- data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
- data/lib/mongoid/association/referenced/belongs_to.rb +1 -1
- data/lib/mongoid/association/referenced/counter_cache.rb +8 -8
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +64 -11
- data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +4 -1
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +10 -14
- data/lib/mongoid/association/referenced/has_many/proxy.rb +12 -9
- data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
- data/lib/mongoid/association/referenced/has_one/proxy.rb +8 -11
- data/lib/mongoid/association/referenced/syncable.rb +2 -2
- data/lib/mongoid/association/relatable.rb +38 -4
- data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
- data/lib/mongoid/attributes/processing.rb +9 -2
- data/lib/mongoid/attributes.rb +30 -27
- data/lib/mongoid/changeable.rb +37 -2
- data/lib/mongoid/clients/options.rb +4 -0
- data/lib/mongoid/clients/sessions.rb +2 -14
- data/lib/mongoid/config/environment.rb +20 -4
- data/lib/mongoid/config.rb +25 -10
- data/lib/mongoid/contextual/aggregable/memory.rb +23 -15
- data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
- data/lib/mongoid/contextual/map_reduce.rb +2 -2
- data/lib/mongoid/contextual/memory.rb +176 -17
- data/lib/mongoid/contextual/mongo.rb +226 -206
- data/lib/mongoid/contextual/none.rb +66 -4
- data/lib/mongoid/copyable.rb +32 -8
- data/lib/mongoid/criteria/includable.rb +24 -20
- data/lib/mongoid/criteria/marshalable.rb +10 -2
- data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -13
- data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
- data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +0 -14
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -1
- data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
- data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
- data/lib/mongoid/criteria/queryable/optional.rb +3 -9
- data/lib/mongoid/criteria/queryable/options.rb +1 -1
- data/lib/mongoid/criteria/queryable/selectable.rb +28 -34
- data/lib/mongoid/criteria/queryable/selector.rb +89 -4
- data/lib/mongoid/criteria/queryable/smash.rb +39 -6
- data/lib/mongoid/criteria/queryable.rb +11 -6
- data/lib/mongoid/criteria.rb +1 -26
- data/lib/mongoid/deprecable.rb +36 -0
- data/lib/mongoid/deprecation.rb +25 -0
- data/lib/mongoid/document.rb +96 -32
- data/lib/mongoid/errors/document_not_found.rb +29 -8
- data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
- data/lib/mongoid/errors/invalid_field.rb +5 -1
- data/lib/mongoid/errors/invalid_field_type.rb +26 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
- data/lib/mongoid/errors.rb +2 -2
- data/lib/mongoid/extensions/array.rb +8 -6
- data/lib/mongoid/extensions/big_decimal.rb +29 -10
- data/lib/mongoid/extensions/binary.rb +42 -0
- data/lib/mongoid/extensions/boolean.rb +8 -2
- data/lib/mongoid/extensions/date.rb +26 -20
- data/lib/mongoid/extensions/date_time.rb +1 -1
- data/lib/mongoid/extensions/float.rb +4 -5
- data/lib/mongoid/extensions/hash.rb +12 -5
- data/lib/mongoid/extensions/integer.rb +4 -5
- data/lib/mongoid/extensions/object.rb +2 -0
- data/lib/mongoid/extensions/range.rb +41 -10
- data/lib/mongoid/extensions/regexp.rb +11 -4
- data/lib/mongoid/extensions/set.rb +11 -4
- data/lib/mongoid/extensions/string.rb +2 -13
- data/lib/mongoid/extensions/symbol.rb +3 -14
- data/lib/mongoid/extensions/time.rb +27 -16
- data/lib/mongoid/extensions/time_with_zone.rb +1 -2
- data/lib/mongoid/extensions.rb +1 -0
- data/lib/mongoid/factory.rb +42 -7
- data/lib/mongoid/fields/foreign_key.rb +7 -0
- data/lib/mongoid/fields/validators/macro.rb +3 -9
- data/lib/mongoid/fields.rb +194 -28
- data/lib/mongoid/findable.rb +27 -7
- data/lib/mongoid/indexable/specification.rb +1 -1
- data/lib/mongoid/indexable/validators/options.rb +4 -1
- data/lib/mongoid/interceptable.rb +69 -9
- data/lib/mongoid/persistable/creatable.rb +14 -5
- data/lib/mongoid/persistable/updatable.rb +12 -5
- data/lib/mongoid/persistable/upsertable.rb +1 -1
- data/lib/mongoid/persistence_context.rb +19 -2
- data/lib/mongoid/query_cache.rb +6 -258
- data/lib/mongoid/railties/controller_runtime.rb +1 -1
- data/lib/mongoid/reloadable.rb +7 -3
- data/lib/mongoid/selectable.rb +1 -2
- data/lib/mongoid/stateful.rb +27 -1
- data/lib/mongoid/timestamps/created.rb +1 -1
- data/lib/mongoid/timestamps/updated.rb +1 -1
- data/lib/mongoid/touchable.rb +2 -3
- data/lib/mongoid/traversable.rb +5 -1
- data/lib/mongoid/validatable/uniqueness.rb +2 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/warnings.rb +28 -0
- data/lib/mongoid.rb +2 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +11 -5
- data/spec/config/mongoid.yml +16 -0
- data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
- data/spec/integration/app_spec.rb +28 -26
- data/spec/integration/associations/belongs_to_spec.rb +18 -0
- data/spec/integration/associations/embedded_dirty_spec.rb +28 -0
- data/spec/integration/associations/embedded_spec.rb +15 -0
- data/spec/integration/associations/embeds_many_spec.rb +15 -2
- data/spec/integration/associations/embeds_one_spec.rb +18 -0
- data/spec/integration/associations/foreign_key_spec.rb +9 -0
- data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
- data/spec/integration/associations/has_one_spec.rb +97 -1
- data/spec/integration/associations/scope_option_spec.rb +1 -1
- data/spec/integration/callbacks_models.rb +95 -1
- data/spec/integration/callbacks_spec.rb +226 -4
- data/spec/integration/criteria/range_spec.rb +95 -1
- data/spec/integration/discriminator_key_spec.rb +115 -76
- data/spec/integration/dots_and_dollars_spec.rb +277 -0
- data/spec/integration/matcher_examples_spec.rb +20 -13
- data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
- data/spec/integration/matcher_operator_spec.rb +3 -5
- data/spec/integration/persistence/range_field_spec.rb +350 -0
- data/spec/lite_spec_helper.rb +1 -1
- data/spec/mongoid/association/counter_cache_spec.rb +1 -1
- data/spec/mongoid/association/depending_spec.rb +9 -9
- data/spec/mongoid/association/eager_spec.rb +2 -1
- data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
- data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
- data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +219 -8
- data/spec/mongoid/association/embedded/embeds_many_models.rb +157 -0
- data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
- data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
- data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
- data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
- data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
- data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
- data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
- data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
- data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +67 -4
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
- data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +8 -8
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +82 -13
- data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
- data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
- data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
- data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
- data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
- data/spec/mongoid/association/syncable_spec.rb +14 -0
- data/spec/mongoid/atomic/paths_spec.rb +0 -14
- data/spec/mongoid/atomic_spec.rb +22 -0
- data/spec/mongoid/attributes/nested_spec.rb +80 -11
- data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
- data/spec/mongoid/attributes/projector_spec.rb +1 -5
- data/spec/mongoid/attributes_spec.rb +524 -27
- data/spec/mongoid/changeable_spec.rb +130 -13
- data/spec/mongoid/clients/factory_spec.rb +34 -42
- data/spec/mongoid/clients/options_spec.rb +1 -0
- data/spec/mongoid/clients/sessions_spec.rb +0 -38
- data/spec/mongoid/clients_spec.rb +32 -2
- data/spec/mongoid/config/environment_spec.rb +39 -1
- data/spec/mongoid/config_spec.rb +104 -13
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
- data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
- data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
- data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
- data/spec/mongoid/contextual/memory_spec.rb +1337 -69
- data/spec/mongoid/contextual/mongo_spec.rb +1105 -172
- data/spec/mongoid/contextual/none_spec.rb +38 -0
- data/spec/mongoid/copyable_spec.rb +451 -1
- data/spec/mongoid/criteria/findable_spec.rb +86 -210
- data/spec/mongoid/criteria/includable_spec.rb +1492 -0
- data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
- data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
- data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
- data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
- data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/optional_spec.rb +0 -484
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +289 -124
- data/spec/mongoid/criteria/queryable/selector_spec.rb +14 -2
- data/spec/mongoid/criteria_spec.rb +474 -1198
- data/spec/mongoid/document_fields_spec.rb +173 -24
- data/spec/mongoid/document_spec.rb +32 -41
- data/spec/mongoid/errors/document_not_found_spec.rb +76 -0
- data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
- data/spec/mongoid/errors/no_environment_spec.rb +3 -3
- data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
- data/spec/mongoid/extensions/array_spec.rb +16 -2
- data/spec/mongoid/extensions/big_decimal_spec.rb +697 -212
- data/spec/mongoid/extensions/binary_spec.rb +44 -9
- data/spec/mongoid/extensions/boolean_spec.rb +68 -82
- data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
- data/spec/mongoid/extensions/date_spec.rb +71 -1
- data/spec/mongoid/extensions/date_time_spec.rb +15 -9
- data/spec/mongoid/extensions/float_spec.rb +48 -76
- data/spec/mongoid/extensions/hash_spec.rb +30 -0
- data/spec/mongoid/extensions/integer_spec.rb +45 -66
- data/spec/mongoid/extensions/range_spec.rb +255 -54
- data/spec/mongoid/extensions/regexp_spec.rb +58 -33
- data/spec/mongoid/extensions/set_spec.rb +106 -0
- data/spec/mongoid/extensions/string_spec.rb +53 -25
- data/spec/mongoid/extensions/symbol_spec.rb +18 -25
- data/spec/mongoid/extensions/time_spec.rb +634 -66
- data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
- data/spec/mongoid/factory_spec.rb +61 -1
- data/spec/mongoid/fields_spec.rb +321 -50
- data/spec/mongoid/findable_spec.rb +80 -15
- data/spec/mongoid/indexable/specification_spec.rb +2 -2
- data/spec/mongoid/indexable_spec.rb +16 -19
- data/spec/mongoid/interceptable_spec.rb +584 -5
- data/spec/mongoid/interceptable_spec_models.rb +235 -4
- data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
- data/spec/mongoid/mongoizable_spec.rb +285 -0
- data/spec/mongoid/persistable/creatable_spec.rb +2 -2
- data/spec/mongoid/persistable/deletable_spec.rb +2 -2
- data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
- data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
- data/spec/mongoid/persistence_context_spec.rb +50 -1
- data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
- data/spec/mongoid/query_cache_spec.rb +0 -154
- data/spec/mongoid/reloadable_spec.rb +35 -2
- data/spec/mongoid/scopable_spec.rb +21 -1
- data/spec/mongoid/shardable_spec.rb +14 -0
- data/spec/mongoid/stateful_spec.rb +28 -0
- data/spec/mongoid/timestamps_spec.rb +390 -0
- data/spec/mongoid/timestamps_spec_models.rb +67 -0
- data/spec/mongoid/touchable_spec.rb +116 -0
- data/spec/mongoid/touchable_spec_models.rb +12 -8
- data/spec/mongoid/traversable_spec.rb +4 -11
- data/spec/mongoid/validatable/presence_spec.rb +1 -1
- data/spec/mongoid/validatable/uniqueness_spec.rb +60 -31
- data/spec/mongoid/warnings_spec.rb +35 -0
- data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
- data/spec/rails/mongoid_spec.rb +4 -16
- data/spec/shared/lib/mrss/constraints.rb +8 -16
- data/spec/shared/lib/mrss/docker_runner.rb +23 -3
- data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +32 -1
- data/spec/shared/share/Dockerfile.erb +34 -48
- data/spec/shared/shlib/config.sh +27 -0
- data/spec/shared/shlib/server.sh +32 -19
- data/spec/shared/shlib/set_env.sh +37 -0
- data/spec/support/constraints.rb +24 -0
- data/spec/support/macros.rb +39 -0
- data/spec/support/models/augmentation.rb +12 -0
- data/spec/support/models/band.rb +3 -0
- data/spec/support/models/catalog.rb +24 -0
- data/spec/support/models/circus.rb +3 -0
- data/spec/support/models/code.rb +2 -0
- data/spec/support/models/fanatic.rb +8 -0
- data/spec/support/models/implant.rb +9 -0
- data/spec/support/models/label.rb +2 -0
- data/spec/support/models/membership.rb +1 -0
- data/spec/support/models/passport.rb +9 -0
- data/spec/support/models/person.rb +1 -0
- data/spec/support/models/player.rb +2 -0
- data/spec/support/models/powerup.rb +12 -0
- data/spec/support/models/registry.rb +1 -0
- data/spec/support/models/school.rb +14 -0
- data/spec/support/models/shield.rb +18 -0
- data/spec/support/models/student.rb +14 -0
- data/spec/support/models/weapon.rb +12 -0
- data/spec/support/schema_maps/schema_map_aws.json +17 -0
- data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_azure.json +17 -0
- data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_gcp.json +17 -0
- data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_kmip.json +17 -0
- data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_local.json +18 -0
- data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
- data/spec/support/spec_config.rb +4 -0
- data.tar.gz.sig +0 -0
- metadata +76 -13
- metadata.gz.sig +0 -0
- data/lib/mongoid/errors/eager_load.rb +0 -23
- data/lib/mongoid/errors/invalid_value.rb +0 -17
- data/spec/mongoid/errors/eager_load_spec.rb +0 -31
data/spec/mongoid/fields_spec.rb
CHANGED
@@ -393,6 +393,22 @@ describe Mongoid::Fields do
|
|
393
393
|
it "converts :time to Time" do
|
394
394
|
expect(klass.field(:test, type: :time).type).to be(Time)
|
395
395
|
end
|
396
|
+
|
397
|
+
context 'when using an unknown symbol' do
|
398
|
+
it 'raises InvalidFieldType' do
|
399
|
+
lambda do
|
400
|
+
klass.field(:test, type: :bogus)
|
401
|
+
end.should raise_error(Mongoid::Errors::InvalidFieldType, /defines a field 'test' with an unknown type value :bogus/)
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
context 'when using an unknown string' do
|
406
|
+
it 'raises InvalidFieldType' do
|
407
|
+
lambda do
|
408
|
+
klass.field(:test, type: 'bogus')
|
409
|
+
end.should raise_error(Mongoid::Errors::InvalidFieldType, /defines a field 'test' with an unknown type value "bogus"/)
|
410
|
+
end
|
411
|
+
end
|
396
412
|
end
|
397
413
|
|
398
414
|
context "when the options are valid" do
|
@@ -427,25 +443,25 @@ describe Mongoid::Fields do
|
|
427
443
|
context "when the Symbol type is used" do
|
428
444
|
|
429
445
|
before do
|
430
|
-
Mongoid::
|
431
|
-
@
|
446
|
+
Mongoid::Warnings.class_eval do
|
447
|
+
@symbol_type_deprecated = false
|
432
448
|
end
|
433
449
|
end
|
434
450
|
|
435
451
|
after do
|
436
|
-
|
452
|
+
Label.fields.delete("should_warn")
|
437
453
|
end
|
438
454
|
|
439
455
|
it "warns that the BSON symbol type is deprecated" do
|
440
456
|
expect(Mongoid.logger).to receive(:warn)
|
441
457
|
|
442
|
-
|
458
|
+
Label.field :should_warn, type: Symbol
|
443
459
|
end
|
444
460
|
|
445
461
|
it "warns on first use of Symbol type only" do
|
446
462
|
expect(Mongoid.logger).to receive(:warn).once
|
447
463
|
|
448
|
-
|
464
|
+
Label.field :should_warn, type: Symbol
|
449
465
|
end
|
450
466
|
|
451
467
|
context 'when using Symbol field type in multiple classes' do
|
@@ -456,7 +472,7 @@ describe Mongoid::Fields do
|
|
456
472
|
it "warns on first use of Symbol type only" do
|
457
473
|
expect(Mongoid.logger).to receive(:warn).once
|
458
474
|
|
459
|
-
|
475
|
+
Label.field :should_warn, type: Symbol
|
460
476
|
Truck.field :should_warn, type: Symbol
|
461
477
|
end
|
462
478
|
end
|
@@ -466,7 +482,7 @@ describe Mongoid::Fields do
|
|
466
482
|
|
467
483
|
it "raises an error" do
|
468
484
|
expect {
|
469
|
-
|
485
|
+
Label.field :unacceptable, bad: true
|
470
486
|
}.to raise_error(Mongoid::Errors::InvalidFieldOption)
|
471
487
|
end
|
472
488
|
end
|
@@ -568,8 +584,144 @@ describe Mongoid::Fields do
|
|
568
584
|
context "when the attribute has been assigned" do
|
569
585
|
|
570
586
|
it "returns the attribute before type cast" do
|
571
|
-
person.age = "
|
572
|
-
expect(person.age_before_type_cast).to eq("
|
587
|
+
person.age = "42"
|
588
|
+
expect(person.age_before_type_cast).to eq("42")
|
589
|
+
end
|
590
|
+
end
|
591
|
+
|
592
|
+
context "when reloading" do
|
593
|
+
|
594
|
+
let(:product) do
|
595
|
+
Product.create!(price: '1')
|
596
|
+
end
|
597
|
+
|
598
|
+
before do
|
599
|
+
product.reload
|
600
|
+
end
|
601
|
+
|
602
|
+
it "resets the attributes_before_type_cast to the attributes hash" do
|
603
|
+
expect(product.attributes_before_type_cast).to eq(product.attributes)
|
604
|
+
end
|
605
|
+
|
606
|
+
it "the *_before_type_cast method returns the demongoized value" do
|
607
|
+
expect(product.price_before_type_cast).to eq(1)
|
608
|
+
end
|
609
|
+
end
|
610
|
+
|
611
|
+
context "when reloading and writing a demongoizable value" do
|
612
|
+
|
613
|
+
let(:product) do
|
614
|
+
Product.create!.tap do |product|
|
615
|
+
Product.collection.update_one({ _id: product.id }, { :$set => { price: '1' }})
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
619
|
+
before do
|
620
|
+
product.reload
|
621
|
+
end
|
622
|
+
|
623
|
+
it "resets the attributes_before_type_cast to the attributes hash" do
|
624
|
+
expect(product.attributes_before_type_cast).to eq(product.attributes)
|
625
|
+
end
|
626
|
+
|
627
|
+
it "the *_before_type_cast method returns the mongoized value" do
|
628
|
+
expect(product.price_before_type_cast).to eq('1')
|
629
|
+
end
|
630
|
+
end
|
631
|
+
|
632
|
+
context "when reading from the db" do
|
633
|
+
|
634
|
+
let(:product) do
|
635
|
+
Product.create!(price: '1')
|
636
|
+
end
|
637
|
+
|
638
|
+
let(:from_db) do
|
639
|
+
Product.find(product.id)
|
640
|
+
end
|
641
|
+
|
642
|
+
it "resets the attributes_before_type_cast to the attributes hash" do
|
643
|
+
expect(from_db.attributes_before_type_cast).to eq(from_db.attributes)
|
644
|
+
end
|
645
|
+
|
646
|
+
it "the *_before_type_cast method returns the demongoized value" do
|
647
|
+
expect(from_db.price_before_type_cast).to eq(1)
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
context "when reading from the db after writing a demongoizable value" do
|
652
|
+
|
653
|
+
let(:product) do
|
654
|
+
Product.create!.tap do |product|
|
655
|
+
Product.collection.update_one({ _id: product.id }, { :$set => { price: '1' }})
|
656
|
+
end
|
657
|
+
end
|
658
|
+
|
659
|
+
let(:from_db) do
|
660
|
+
Product.find(product.id)
|
661
|
+
end
|
662
|
+
|
663
|
+
it "resets the attributes_before_type_cast to the attributes hash" do
|
664
|
+
expect(from_db.attributes_before_type_cast).to eq(from_db.attributes)
|
665
|
+
end
|
666
|
+
|
667
|
+
it "the *_before_type_cast method returns the mongoized value" do
|
668
|
+
expect(from_db.price_before_type_cast).to eq('1')
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
context "when making a new model" do
|
673
|
+
|
674
|
+
context "when using new with no options" do
|
675
|
+
let(:product) { Product.new }
|
676
|
+
|
677
|
+
it "sets the attributes_before_type_cast to the attributes hash" do
|
678
|
+
expect(product.attributes_before_type_cast).to eq(product.attributes)
|
679
|
+
end
|
680
|
+
end
|
681
|
+
|
682
|
+
context "when using new with options" do
|
683
|
+
let(:product) { Product.new(price: '1') }
|
684
|
+
|
685
|
+
let(:abtc) do
|
686
|
+
product.attributes.merge('price' => '1')
|
687
|
+
end
|
688
|
+
|
689
|
+
it "has the attributes before type cast" do
|
690
|
+
expect(product.attributes_before_type_cast).to eq(abtc)
|
691
|
+
end
|
692
|
+
end
|
693
|
+
|
694
|
+
context "when persisting the model" do
|
695
|
+
let(:product) { Product.new(price: '1') }
|
696
|
+
|
697
|
+
let(:abtc) do
|
698
|
+
product.attributes.merge('price' => '1')
|
699
|
+
end
|
700
|
+
|
701
|
+
before do
|
702
|
+
expect(product.attributes_before_type_cast).to eq(abtc)
|
703
|
+
product.save!
|
704
|
+
end
|
705
|
+
|
706
|
+
it "resets the attributes_before_type_cast to the attributes" do
|
707
|
+
expect(product.attributes_before_type_cast).to eq(product.attributes)
|
708
|
+
end
|
709
|
+
end
|
710
|
+
|
711
|
+
context "when using create! without options" do
|
712
|
+
let(:product) { Product.create! }
|
713
|
+
|
714
|
+
it "resets the attributes_before_type_cast to the attributes" do
|
715
|
+
expect(product.attributes_before_type_cast).to eq(product.attributes)
|
716
|
+
end
|
717
|
+
end
|
718
|
+
|
719
|
+
context "when using create! with options" do
|
720
|
+
let(:product) { Product.create!(price: '1') }
|
721
|
+
|
722
|
+
it "resets the attributes_before_type_cast to the attributes" do
|
723
|
+
expect(product.attributes_before_type_cast).to eq(product.attributes)
|
724
|
+
end
|
573
725
|
end
|
574
726
|
end
|
575
727
|
end
|
@@ -725,6 +877,22 @@ describe Mongoid::Fields do
|
|
725
877
|
end
|
726
878
|
end
|
727
879
|
end
|
880
|
+
|
881
|
+
context "when the field needs to be mongoized" do
|
882
|
+
|
883
|
+
before do
|
884
|
+
product.price = "1"
|
885
|
+
product.save!
|
886
|
+
end
|
887
|
+
|
888
|
+
it "mongoizes the value" do
|
889
|
+
expect(product.price).to eq(1)
|
890
|
+
end
|
891
|
+
|
892
|
+
it "stores the value in the mongoized form" do
|
893
|
+
expect(product.attributes_before_type_cast["price"]).to eq(1)
|
894
|
+
end
|
895
|
+
end
|
728
896
|
end
|
729
897
|
|
730
898
|
describe "#defaults" do
|
@@ -861,7 +1029,7 @@ describe Mongoid::Fields do
|
|
861
1029
|
it "raises an error" do
|
862
1030
|
expect {
|
863
1031
|
Person.field(meth)
|
864
|
-
}.to raise_error(Mongoid::Errors::InvalidField)
|
1032
|
+
}.to raise_error(Mongoid::Errors::InvalidField, /Defining a field named '#{meth}' is not allowed/)
|
865
1033
|
end
|
866
1034
|
end
|
867
1035
|
end
|
@@ -988,7 +1156,7 @@ describe Mongoid::Fields do
|
|
988
1156
|
end
|
989
1157
|
|
990
1158
|
it "uses the alias to write the attribute" do
|
991
|
-
(person.alias =
|
1159
|
+
expect(person.alias = true).to be true
|
992
1160
|
end
|
993
1161
|
|
994
1162
|
it "uses the alias to read the attribute" do
|
@@ -1000,7 +1168,7 @@ describe Mongoid::Fields do
|
|
1000
1168
|
end
|
1001
1169
|
|
1002
1170
|
it "uses the name to write the attribute" do
|
1003
|
-
(person.aliased =
|
1171
|
+
expect(person.aliased = true).to be true
|
1004
1172
|
end
|
1005
1173
|
|
1006
1174
|
it "uses the name to read the attribute" do
|
@@ -1229,71 +1397,147 @@ describe Mongoid::Fields do
|
|
1229
1397
|
|
1230
1398
|
context "when a field is defined as a big decimal" do
|
1231
1399
|
|
1232
|
-
|
1233
|
-
|
1234
|
-
end
|
1235
|
-
|
1236
|
-
let(:decimal) do
|
1237
|
-
BigDecimal("1000000.00")
|
1238
|
-
end
|
1239
|
-
|
1240
|
-
context "when setting to a big decimal" do
|
1400
|
+
context 'when Mongoid.map_big_decimal_to_decimal128 is false' do
|
1401
|
+
config_override :map_big_decimal_to_decimal128, false
|
1241
1402
|
|
1242
|
-
|
1243
|
-
|
1403
|
+
let(:band) do
|
1404
|
+
Band.new(name: "Tool")
|
1244
1405
|
end
|
1245
1406
|
|
1246
|
-
|
1247
|
-
|
1407
|
+
let(:decimal) do
|
1408
|
+
BigDecimal("1000000.00")
|
1248
1409
|
end
|
1249
1410
|
|
1250
|
-
|
1251
|
-
|
1411
|
+
context "when setting to a big decimal" do
|
1412
|
+
|
1413
|
+
before do
|
1414
|
+
band.sales = decimal
|
1415
|
+
end
|
1416
|
+
|
1417
|
+
it "properly persists as a string" do
|
1418
|
+
expect(band.attributes["sales"]).to eq(decimal.to_s)
|
1419
|
+
end
|
1420
|
+
|
1421
|
+
it "returns the proper big decimal" do
|
1422
|
+
expect(band.sales).to eq(decimal)
|
1423
|
+
end
|
1252
1424
|
end
|
1253
|
-
end
|
1254
1425
|
|
1255
|
-
|
1426
|
+
context "when setting to a string" do
|
1256
1427
|
|
1257
|
-
|
1258
|
-
|
1428
|
+
before do
|
1429
|
+
band.sales = decimal.to_s
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
it "properly persists as a string" do
|
1433
|
+
expect(band.attributes["sales"]).to eq(decimal.to_s)
|
1434
|
+
end
|
1435
|
+
|
1436
|
+
it "returns the proper big decimal" do
|
1437
|
+
expect(band.sales).to eq(decimal)
|
1438
|
+
end
|
1259
1439
|
end
|
1260
1440
|
|
1261
|
-
|
1262
|
-
|
1441
|
+
context "when setting to an integer" do
|
1442
|
+
|
1443
|
+
before do
|
1444
|
+
band.sales = decimal.to_i
|
1445
|
+
end
|
1446
|
+
|
1447
|
+
it "properly persists as a string" do
|
1448
|
+
expect(band.attributes["sales"]).to eq("1000000")
|
1449
|
+
end
|
1450
|
+
|
1451
|
+
it "returns the proper big decimal" do
|
1452
|
+
expect(band.sales).to eq(decimal)
|
1453
|
+
end
|
1263
1454
|
end
|
1264
1455
|
|
1265
|
-
|
1266
|
-
|
1456
|
+
context "when setting to a float" do
|
1457
|
+
|
1458
|
+
before do
|
1459
|
+
band.sales = decimal.to_f
|
1460
|
+
end
|
1461
|
+
|
1462
|
+
it "properly persists as a string" do
|
1463
|
+
expect(band.attributes["sales"]).to eq(decimal.to_s)
|
1464
|
+
end
|
1465
|
+
|
1466
|
+
it "returns the proper big decimal" do
|
1467
|
+
expect(band.sales).to eq(decimal)
|
1468
|
+
end
|
1267
1469
|
end
|
1268
1470
|
end
|
1269
1471
|
|
1270
|
-
context
|
1472
|
+
context 'when Mongoid.map_big_decimal_to_decimal128 is true' do
|
1473
|
+
config_override :map_big_decimal_to_decimal128, true
|
1271
1474
|
|
1272
|
-
|
1273
|
-
|
1475
|
+
let(:band) do
|
1476
|
+
Band.new(name: "Tool")
|
1274
1477
|
end
|
1275
1478
|
|
1276
|
-
|
1277
|
-
|
1479
|
+
let(:decimal) do
|
1480
|
+
BigDecimal("1000000.00")
|
1278
1481
|
end
|
1279
1482
|
|
1280
|
-
|
1281
|
-
|
1483
|
+
context "when setting to a big decimal" do
|
1484
|
+
|
1485
|
+
before do
|
1486
|
+
band.sales = decimal
|
1487
|
+
end
|
1488
|
+
|
1489
|
+
it "properly persists as a BSON::Decimal128" do
|
1490
|
+
expect(band.attributes["sales"]).to eq(BSON::Decimal128.new(decimal))
|
1491
|
+
end
|
1492
|
+
|
1493
|
+
it "returns the proper big decimal" do
|
1494
|
+
expect(band.sales).to eq(decimal)
|
1495
|
+
end
|
1282
1496
|
end
|
1283
|
-
end
|
1284
1497
|
|
1285
|
-
|
1498
|
+
context "when setting to a string" do
|
1286
1499
|
|
1287
|
-
|
1288
|
-
|
1500
|
+
before do
|
1501
|
+
band.sales = decimal.to_s
|
1502
|
+
end
|
1503
|
+
|
1504
|
+
it "persists as a BSON::Decimal128" do
|
1505
|
+
expect(band.attributes["sales"]).to eq(BSON::Decimal128.new(decimal.to_s))
|
1506
|
+
end
|
1507
|
+
|
1508
|
+
it "returns the proper big decimal" do
|
1509
|
+
expect(band.sales).to eq(decimal)
|
1510
|
+
end
|
1289
1511
|
end
|
1290
1512
|
|
1291
|
-
|
1292
|
-
|
1513
|
+
context "when setting to an integer" do
|
1514
|
+
|
1515
|
+
before do
|
1516
|
+
band.sales = decimal.to_i
|
1517
|
+
end
|
1518
|
+
|
1519
|
+
it "persists as a BSON::Decimal128" do
|
1520
|
+
expect(band.attributes["sales"]).to eq(BSON::Decimal128.new(decimal.to_i.to_s))
|
1521
|
+
end
|
1522
|
+
|
1523
|
+
it "returns the proper big decimal" do
|
1524
|
+
expect(band.sales).to eq(decimal)
|
1525
|
+
end
|
1293
1526
|
end
|
1294
1527
|
|
1295
|
-
|
1296
|
-
|
1528
|
+
context "when setting to a float" do
|
1529
|
+
|
1530
|
+
before do
|
1531
|
+
band.sales = decimal.to_f
|
1532
|
+
end
|
1533
|
+
|
1534
|
+
it "properly persists as a BSON::Decimal128" do
|
1535
|
+
expect(band.attributes["sales"]).to eq(BSON::Decimal128.new(decimal.to_f.to_s))
|
1536
|
+
end
|
1537
|
+
|
1538
|
+
it "returns the proper big decimal" do
|
1539
|
+
expect(band.sales).to eq(decimal)
|
1540
|
+
end
|
1297
1541
|
end
|
1298
1542
|
end
|
1299
1543
|
end
|
@@ -1620,6 +1864,33 @@ describe Mongoid::Fields do
|
|
1620
1864
|
it_behaves_like 'pre-fix database_field_name'
|
1621
1865
|
end
|
1622
1866
|
end
|
1867
|
+
|
1868
|
+
context 'when getting the database field name of a belongs_to associations' do
|
1869
|
+
# These tests only apply when the flag is not set
|
1870
|
+
config_override :broken_alias_handling, false
|
1871
|
+
|
1872
|
+
context "when the broken_alias_handling is not set" do
|
1873
|
+
context "when the association is the last item" do
|
1874
|
+
let(:name) do
|
1875
|
+
Game.database_field_name("person")
|
1876
|
+
end
|
1877
|
+
|
1878
|
+
it "gets the alias" do
|
1879
|
+
expect(name).to eq("person_id")
|
1880
|
+
end
|
1881
|
+
end
|
1882
|
+
|
1883
|
+
context "when the association is not the last item" do
|
1884
|
+
let(:name) do
|
1885
|
+
Game.database_field_name("person.name")
|
1886
|
+
end
|
1887
|
+
|
1888
|
+
it "gets the alias" do
|
1889
|
+
expect(name).to eq("person.name")
|
1890
|
+
end
|
1891
|
+
end
|
1892
|
+
end
|
1893
|
+
end
|
1623
1894
|
end
|
1624
1895
|
|
1625
1896
|
describe "#get_field" do
|
@@ -85,7 +85,7 @@ describe Mongoid::Findable do
|
|
85
85
|
it "raises an error" do
|
86
86
|
expect {
|
87
87
|
person.messages.find_by(body: 'bar')
|
88
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
88
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document not found for class Message with attributes/)
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
@@ -144,7 +144,7 @@ describe Mongoid::Findable do
|
|
144
144
|
it "raises an error" do
|
145
145
|
expect {
|
146
146
|
Person.find_by(ssn: "333-22-1111")
|
147
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
147
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document not found for class Person with attributes/)
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
@@ -213,7 +213,7 @@ describe Mongoid::Findable do
|
|
213
213
|
it "raises an error" do
|
214
214
|
expect {
|
215
215
|
Person.find_by!(ssn: "333-22-1111")
|
216
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
216
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound, /Document not found for class Person with attributes/)
|
217
217
|
end
|
218
218
|
end
|
219
219
|
end
|
@@ -229,6 +229,24 @@ describe Mongoid::Findable do
|
|
229
229
|
it "returns the first matching document" do
|
230
230
|
expect(Person.send(method)).to eq(person)
|
231
231
|
end
|
232
|
+
|
233
|
+
it "passes the limit through" do
|
234
|
+
expect(Person.last(1)).to eq([ person ])
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe "#last" do
|
240
|
+
let!(:person) do
|
241
|
+
Person.create!
|
242
|
+
end
|
243
|
+
|
244
|
+
it "returns the first matching document" do
|
245
|
+
expect(Person.last).to eq(person)
|
246
|
+
end
|
247
|
+
|
248
|
+
it "passes the limit through" do
|
249
|
+
expect(Person.last(1)).to eq([ person ])
|
232
250
|
end
|
233
251
|
end
|
234
252
|
|
@@ -472,7 +490,7 @@ describe Mongoid::Findable do
|
|
472
490
|
Band.pluck(:follows)
|
473
491
|
end
|
474
492
|
|
475
|
-
it "returns
|
493
|
+
it "returns an array with nil values" do
|
476
494
|
expect(plucked).to eq([nil, nil, nil])
|
477
495
|
end
|
478
496
|
end
|
@@ -521,10 +539,10 @@ describe Mongoid::Findable do
|
|
521
539
|
end
|
522
540
|
|
523
541
|
context 'when Mongoid is configured to use activesupport time zone' do
|
542
|
+
config_override :use_utc, false
|
543
|
+
config_override :use_activesupport_time_zone, true
|
524
544
|
|
525
545
|
before do
|
526
|
-
Mongoid.use_utc = false
|
527
|
-
Mongoid.use_activesupport_time_zone = true
|
528
546
|
Time.zone = "Asia/Kolkata"
|
529
547
|
end
|
530
548
|
|
@@ -534,8 +552,33 @@ describe Mongoid::Findable do
|
|
534
552
|
end
|
535
553
|
end
|
536
554
|
|
537
|
-
|
538
|
-
|
555
|
+
context 'when distinct does not demongoize' do
|
556
|
+
config_override :legacy_pluck_distinct, true
|
557
|
+
|
558
|
+
let(:distinct) do
|
559
|
+
User.distinct(:last_login).first
|
560
|
+
end
|
561
|
+
|
562
|
+
it 'uses activesupport time zone' do
|
563
|
+
distinct.should be_a(ActiveSupport::TimeWithZone)
|
564
|
+
expect(distinct.to_s).to eql(time.in_time_zone('Asia/Kolkata').to_s)
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
context 'when distinct demongoizes' do
|
569
|
+
config_override :legacy_pluck_distinct, false
|
570
|
+
|
571
|
+
let(:distinct) do
|
572
|
+
User.distinct(:last_login).first
|
573
|
+
end
|
574
|
+
|
575
|
+
it 'uses activesupport time zone' do
|
576
|
+
distinct.should be_a(DateTime)
|
577
|
+
# Time and DateTime have different stringifications:
|
578
|
+
# 2022-03-16T21:12:32+00:00
|
579
|
+
# 2022-03-16 21:12:32 UTC
|
580
|
+
expect(distinct.to_s).to eql(time.in_time_zone('Asia/Kolkata').to_datetime.to_s)
|
581
|
+
end
|
539
582
|
end
|
540
583
|
|
541
584
|
it 'loads other fields accurately' do
|
@@ -544,11 +587,8 @@ describe Mongoid::Findable do
|
|
544
587
|
end
|
545
588
|
|
546
589
|
context 'when Mongoid is not configured to use activesupport time zone' do
|
547
|
-
|
548
|
-
|
549
|
-
Mongoid.use_utc = true
|
550
|
-
Mongoid.use_activesupport_time_zone = false
|
551
|
-
end
|
590
|
+
config_override :use_utc, true
|
591
|
+
config_override :use_activesupport_time_zone, false
|
552
592
|
|
553
593
|
let!(:time) do
|
554
594
|
Time.now.tap do |t|
|
@@ -556,8 +596,33 @@ describe Mongoid::Findable do
|
|
556
596
|
end
|
557
597
|
end
|
558
598
|
|
559
|
-
|
560
|
-
|
599
|
+
context 'when distinct does not demongoize' do
|
600
|
+
config_override :legacy_pluck_distinct, true
|
601
|
+
|
602
|
+
let(:distinct) do
|
603
|
+
User.distinct(:last_login).first
|
604
|
+
end
|
605
|
+
|
606
|
+
it 'uses utc' do
|
607
|
+
distinct.should be_a(Time)
|
608
|
+
expect(distinct.to_s).to eql(time.utc.to_s)
|
609
|
+
end
|
610
|
+
end
|
611
|
+
|
612
|
+
context 'when distinct demongoizes' do
|
613
|
+
config_override :legacy_pluck_distinct, false
|
614
|
+
|
615
|
+
let(:distinct) do
|
616
|
+
User.distinct(:last_login).first
|
617
|
+
end
|
618
|
+
|
619
|
+
it 'uses utc' do
|
620
|
+
distinct.should be_a(DateTime)
|
621
|
+
# Time and DateTime have different stringifications:
|
622
|
+
# 2022-03-16T21:12:32+00:00
|
623
|
+
# 2022-03-16 21:12:32 UTC
|
624
|
+
expect(distinct.to_s).to eql(time.utc.to_datetime.to_s)
|
625
|
+
end
|
561
626
|
end
|
562
627
|
|
563
628
|
it 'loads other fields accurately' do
|
@@ -85,7 +85,7 @@ describe Mongoid::Indexable::Specification do
|
|
85
85
|
Band,
|
86
86
|
{ name: 1, title: 1, years: -1 },
|
87
87
|
background: true,
|
88
|
-
|
88
|
+
unique: true
|
89
89
|
)
|
90
90
|
end
|
91
91
|
|
@@ -98,7 +98,7 @@ describe Mongoid::Indexable::Specification do
|
|
98
98
|
end
|
99
99
|
|
100
100
|
it "normalizes the options" do
|
101
|
-
expect(spec.options).to eq(background: true,
|
101
|
+
expect(spec.options).to eq(background: true, unique: true)
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|