4
4
require "mongoid/fields/foreign_key"
5
5
require "mongoid/fields/localized"
6
6
require "mongoid/fields/validators"
7
+ require "mongoid/fields/field_types"
7
8
8
9
module Mongoid
9
10
@@ -14,26 +15,8 @@ module Fields
14
15
StringifiedSymbol = Mongoid ::StringifiedSymbol
15
16
Boolean = Mongoid ::Boolean
16
17
17
- # For fields defined with symbols use the correct class.
18
- TYPE_MAPPINGS = {
19
- array : Array ,
20
- big_decimal : BigDecimal ,
21
- binary : BSON ::Binary ,
22
- boolean : Mongoid ::Boolean ,
23
- date : Date ,
24
- date_time : DateTime ,
25
- float : Float ,
26
- hash : Hash ,
27
- integer : Integer ,
28
- object_id : BSON ::ObjectId ,
29
- range : Range ,
30
- regexp : Regexp ,
31
- set : Set ,
32
- string : String ,
33
- stringified_symbol : StringifiedSymbol ,
34
- symbol : Symbol ,
35
- time : Time
36
- } . with_indifferent_access
18
+ # @deprecated
19
+ TYPE_MAPPINGS = ::Mongoid ::Fields ::FieldTypes ::DEFAULT_MAPPING
37
20
38
21
# Constant for all names of the _id field in a document.
39
22
#
@@ -45,7 +28,7 @@ module Fields
45
28
# BSON classes that are not supported as field types
46
29
#
47
30
# @api private
48
- INVALID_BSON_CLASSES = [ BSON ::Decimal128 , BSON ::Int32 , BSON ::Int64 ] . freeze
31
+ UNSUPPORTED_BSON_TYPES = [ BSON ::Decimal128 , BSON ::Int32 , BSON ::Int64 ] . freeze
49
32
50
33
module ClassMethods
51
34
# Returns the list of id fields for this model class, as both strings
@@ -274,6 +257,33 @@ def validate_writable_field_name!(name)
274
257
275
258
class << self
276
259
260
+ # DSL method used for configuration readability, typically in
261
+ # an initializer.
262
+ #
263
+ # @example
264
+ # Mongoid::Fields.configure do
265
+ # # do configuration
266
+ # end
267
+ def configure ( &block )
268
+ instance_exec ( &block )
269
+ end
270
+
271
+ # Defines a field type mapping, for later use in field :type option.
272
+ #
273
+ # @example
274
+ # Mongoid::Fields.configure do
275
+ # define_type :point, Point
276
+ # end
277
+ #
278
+ # @param [ Symbol | String ] field_type the identifier of the
279
+ # defined type. This identifier will be accessible as either a
280
+ # string or a symbol regardless of the type passed to this method.
281
+ # @param [ Module ] klass the class of the defined type, which must
282
+ # include mongoize, demongoize, and evolve methods.
283
+ def define_type ( field_type , klass )
284
+ Fields ::FieldTypes . define_type ( field_type , klass )
285
+ end
286
+
277
287
# Stores the provided block to be run when the option name specified is
278
288
# defined on a field.
279
289
#
@@ -282,8 +292,10 @@ class << self
282
292
# provided in the field definition -- even if it is false or nil.
283
293
#
284
294
# @example
285
- # Mongoid::Fields.option :required do |model, field, value|
286
- # model.validates_presence_of field if value
295
+ # Mongoid::Fields.configure do
296
+ # option :required do |model, field, value|
297
+ # model.validates_presence_of field.name if value
298
+ # end
287
299
# end
288
300
#
289
301
# @param [ Symbol ] option_name the option name to match against
@@ -767,32 +779,28 @@ def remove_defaults(name)
767
779
768
780
def field_for ( name , options )
769
781
opts = options . merge ( klass : self )
770
- type_mapping = TYPE_MAPPINGS [ options [ :type ] ]
771
- opts [ :type ] = type_mapping || unmapped_type ( options )
772
- if !opts [ :type ] . is_a? ( Class )
773
- raise Errors ::InvalidFieldType . new ( self , name , options [ :type ] )
774
- else
775
- if INVALID_BSON_CLASSES . include? ( opts [ :type ] )
776
- warn_message = "Using #{ opts [ :type ] } as the field type is not supported. "
777
- if opts [ :type ] == BSON ::Decimal128
778
- warn_message += "In BSON <= 4, the BSON::Decimal128 type will work as expected for both storing and querying, but will return a BigDecimal on query in BSON 5+."
779
- else
780
- warn_message += "Saving values of this type to the database will work as expected, however, querying them will return a value of the native Ruby Integer type."
781
- end
782
- Mongoid . logger . warn ( warn_message )
782
+ if type = options [ :type ]
783
+ type = Fields ::FieldTypes . get ( type )
784
+ unless type
785
+ raise Mongoid ::Errors ::UnknownFieldType . new ( self . name , name , type )
783
786
end
787
+ opts [ :type ] = type
788
+ warn_unsupported_bson_type ( type )
784
789
end
785
790
return Fields ::Localized . new ( name , opts ) if options [ :localize ]
786
791
return Fields ::ForeignKey . new ( name , opts ) if options [ :identity ]
787
792
Fields ::Standard . new ( name , opts )
788
793
end
789
794
790
- def unmapped_type ( options )
791
- if "Boolean" == options [ :type ] . to_s
792
- Mongoid ::Boolean
795
+ def warn_unsupported_bson_type ( type )
796
+ return unless UNSUPPORTED_BSON_TYPES . include? ( type )
797
+ warn_message = "Using #{ type } as the field type is not supported. "
798
+ if type == BSON ::Decimal128
799
+ warn_message += "In BSON <= 4, the BSON::Decimal128 type will work as expected for both storing and querying, but will return a BigDecimal on query in BSON 5+."
793
800
else
794
- options [ : type] || Object
801
+ warn_message += "Saving values of this type to the database will work as expected, however, querying them will return a value of the native Ruby Integer type."
795
802
end
803
+ Mongoid . logger . warn ( warn_message )
796
804
end
797
805
end
798
806
end
0 commit comments