44require "mongoid/fields/foreign_key"
55require "mongoid/fields/localized"
66require "mongoid/fields/validators"
7+ require "mongoid/fields/field_types"
78
89module Mongoid
910
@@ -14,26 +15,8 @@ module Fields
1415 StringifiedSymbol = Mongoid ::StringifiedSymbol
1516 Boolean = Mongoid ::Boolean
1617
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
3720
3821 # Constant for all names of the _id field in a document.
3922 #
@@ -45,7 +28,7 @@ module Fields
4528 # BSON classes that are not supported as field types
4629 #
4730 # @api private
48- INVALID_BSON_CLASSES = [ BSON ::Decimal128 , BSON ::Int32 , BSON ::Int64 ] . freeze
31+ UNSUPPORTED_BSON_TYPES = [ BSON ::Decimal128 , BSON ::Int32 , BSON ::Int64 ] . freeze
4932
5033 module ClassMethods
5134 # Returns the list of id fields for this model class, as both strings
@@ -274,6 +257,33 @@ def validate_writable_field_name!(name)
274257
275258 class << self
276259
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+
277287 # Stores the provided block to be run when the option name specified is
278288 # defined on a field.
279289 #
@@ -282,8 +292,10 @@ class << self
282292 # provided in the field definition -- even if it is false or nil.
283293 #
284294 # @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
287299 # end
288300 #
289301 # @param [ Symbol ] option_name the option name to match against
@@ -767,32 +779,28 @@ def remove_defaults(name)
767779
768780 def field_for ( name , options )
769781 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 )
783786 end
787+ opts [ :type ] = type
788+ warn_unsupported_bson_type ( type )
784789 end
785790 return Fields ::Localized . new ( name , opts ) if options [ :localize ]
786791 return Fields ::ForeignKey . new ( name , opts ) if options [ :identity ]
787792 Fields ::Standard . new ( name , opts )
788793 end
789794
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+."
793800 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."
795802 end
803+ Mongoid . logger . warn ( warn_message )
796804 end
797805 end
798806 end
0 commit comments