Module: Mongoid::Fields
- Extended by:
- ActiveSupport::Concern
- Included in:
- Composable
- Defined in:
- lib/mongoid/fields.rb,
lib/mongoid/fields/standard.rb,
lib/mongoid/fields/encrypted.rb,
lib/mongoid/fields/localized.rb,
lib/mongoid/fields/foreign_key.rb,
lib/mongoid/fields/validators/macro.rb
Overview
This module defines behavior for fields.
Defined Under Namespace
Modules: ClassMethods, Validators Classes: Encrypted, ForeignKey, Localized, Standard
Constant Summary collapse
- StringifiedSymbol =
Mongoid::StringifiedSymbol
- Boolean =
Mongoid::Boolean
- TYPE_MAPPINGS =
For fields defined with symbols use the correct class.
{ array: Array, big_decimal: BigDecimal, binary: BSON::Binary, boolean: Mongoid::Boolean, date: Date, date_time: DateTime, float: Float, hash: Hash, integer: Integer, object_id: BSON::ObjectId, range: Range, regexp: Regexp, set: Set, string: String, stringified_symbol: StringifiedSymbol, symbol: Symbol, time: Time }.with_indifferent_access
- IDS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Constant for all names of the _id field in a document.
This does not include aliases of _id field.
[ :_id, '_id', ].freeze
- INVALID_BSON_CLASSES =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
BSON classes that are not supported as field types
[ BSON::Decimal128, BSON::Int32, BSON::Int64 ].freeze
Class Method Summary collapse
-
.database_field_name(name, relations, aliased_fields, aliased_associations) ⇒ String
private
Get the name of the provided field as it is stored in the database.
-
.option(option_name, &block) ⇒ Object
Stores the provided block to be run when the option name specified is defined on a field.
-
.options ⇒ Hash
Return a map of custom option names to their handlers.
-
.traverse_association_tree(key, fields, associations, aliased_associations) {|The, The, Whether| ... } ⇒ Field
private
Traverse down the association tree and search for the field for the given key.
Instance Method Summary collapse
-
#apply_default(name) ⇒ Object
Applies a single default value for the given name.
-
#apply_defaults ⇒ Object
Apply all the defaults at once.
-
#apply_post_processed_defaults ⇒ Array<String>
Apply all default values to the document which are procs.
-
#apply_pre_processed_defaults ⇒ Array<String>
Apply all default values to the document which are not procs.
-
#attribute_names ⇒ Array<String>
Returns an array of names for the attributes available on this object.
-
#database_field_name(name) ⇒ String
Get the name of the provided field as it is stored in the database.
-
#dot_dollar_field?(name) ⇒ true | false
private
Does this field start with a dollar sign ($) or contain a dot/period (.)?.
-
#lazy_settable?(field, value) ⇒ true | false
Is the provided field a lazy evaluation?.
-
#using_object_ids? ⇒ true | false
Is the document using object ids?.
-
#validate_writable_field_name!(name) ⇒ Object
private
Validate whether or not the field starts with a dollar sign ($) or contains a dot/period (.).
Class Method Details
.database_field_name(name, relations, aliased_fields, aliased_associations) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Get the name of the provided field as it is stored in the database. Used in determining if the field is aliased or not. Recursively finds aliases for embedded documents and fields, delimited with period “.” character.
Note that this method returns the name of associations as they’re stored in the database, whereas the ‘relations` hash uses their in-code aliases. In order to check for membership in the relations hash, you would first have to look up the string returned from this method in the aliased_associations hash.
This method will not expand the alias of a belongs_to association that is not the last item. For example, if we had a School that has_many Students, and the field name passed was (from the Student’s perspective):
school._id
The alias for a belongs_to association is that association’s _id field. Therefore, expanding out this association would yield:
school_id._id
This is not the correct field name, because the intention here was not to get a property of the _id field. The intention was to get a property of the referenced document. Therefore, if a part of the name passed is a belongs_to association that is not the last part of the name, we won’t expand its alias, and return:
school._id
If the belongs_to association is the last part of the name, we will pass back the _id field.
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 |
# File 'lib/mongoid/fields.rb', line 410 def database_field_name(name, relations, aliased_fields, aliased_associations) return nil unless name.present? key = name.to_s segment, remaining = key.split('.', 2) # Don't get the alias for the field when a belongs_to association # is not the last item. Therefore, get the alias when one of the # following is true: # 1. This is the last item, i.e. there is no remaining. # 2. It is not an association. # 3. It is not a belongs association if !remaining || !relations.key?(segment) || !relations[segment].is_a?(Association::Referenced::BelongsTo) segment = aliased_fields[segment]&.dup || segment end return segment unless remaining relation = relations[aliased_associations[segment] || segment] if relation k = relation.klass "#{segment}.#{database_field_name(remaining, k.relations, k.aliased_fields, k.aliased_associations)}" else "#{segment}.#{remaining}" end end |
.option(option_name, &block) ⇒ Object
Stores the provided block to be run when the option name specified is defined on a field.
No assumptions are made about what functionality the handler might perform, so it will always be called if the ‘option_name` key is provided in the field definition – even if it is false or nil.
293 294 295 |
# File 'lib/mongoid/fields.rb', line 293 def option(option_name, &block) [option_name] = block end |
.options ⇒ Hash
Return a map of custom option names to their handlers.
304 305 306 |
# File 'lib/mongoid/fields.rb', line 304 def @options ||= {} end |
.traverse_association_tree(key, fields, associations, aliased_associations) {|The, The, Whether| ... } ⇒ Field
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Traverse down the association tree and search for the field for the given key. To do this, split the key by ‘.’ and for each part (meth) of the key:
-
If the meth is a field, yield the meth, field, and is_field as true.
-
If the meth is an association, update the klass to the association’s klass, and yield the meth, klass, and is_field as false.
The next iteration will use klass’s fields and associations to continue traversing the tree.
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 |
# File 'lib/mongoid/fields.rb', line 335 def traverse_association_tree(key, fields, associations, aliased_associations) klass = nil field = nil key.split('.').each_with_index do |meth, i| fs = i == 0 ? fields : klass&.fields rs = i == 0 ? associations : klass&.relations as = i == 0 ? aliased_associations : klass&.aliased_associations # Associations can possibly have two "keys", their name and their alias. # The fields name is what is used to store it in the klass's relations # and field hashes, and the alias is what's used to store that field # in the database. The key inputted to this function is the aliased # key. We can convert them back to their names by looking in the # aliased_associations hash. aliased = meth if as && a = as.fetch(meth, nil) aliased = a.to_s end field = nil klass = nil if fs && f = fs[aliased] field = f yield(meth, f, true) if block_given? elsif rs && rel = rs[aliased] klass = rel.klass yield(meth, rel, false) if block_given? else yield(meth, nil, false) if block_given? end end field end |
Instance Method Details
#apply_default(name) ⇒ Object
Applies a single default value for the given name.
178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/mongoid/fields.rb', line 178 def apply_default(name) unless attributes.key?(name) if field = fields[name] default = field.eval_default(self) unless default.nil? || field.lazy? attribute_will_change!(name) attributes[name] = default end end end end |
#apply_defaults ⇒ Object
Apply all the defaults at once.
194 195 196 197 198 |
# File 'lib/mongoid/fields.rb', line 194 def apply_defaults pending_callbacks.delete(:apply_defaults) apply_pre_processed_defaults apply_post_processed_defaults end |
#apply_post_processed_defaults ⇒ Array<String>
Apply all default values to the document which are procs.
165 166 167 168 169 170 |
# File 'lib/mongoid/fields.rb', line 165 def apply_post_processed_defaults pending_callbacks.delete(:apply_post_processed_defaults) post_processed_defaults.each do |name| apply_default(name) end end |
#apply_pre_processed_defaults ⇒ Array<String>
Apply all default values to the document which are not procs.
153 154 155 156 157 |
# File 'lib/mongoid/fields.rb', line 153 def apply_pre_processed_defaults pre_processed_defaults.each do |name| apply_default(name) end end |
#attribute_names ⇒ Array<String>
Returns an array of names for the attributes available on this object.
Provides the field names in an ORM-agnostic way. Rails v3.1+ uses this method to automatically wrap params in JSON requests.
209 210 211 |
# File 'lib/mongoid/fields.rb', line 209 def attribute_names self.class.attribute_names end |
#database_field_name(name) ⇒ String
Get the name of the provided field as it is stored in the database. Used in determining if the field is aliased or not.
222 223 224 |
# File 'lib/mongoid/fields.rb', line 222 def database_field_name(name) self.class.database_field_name(name) end |
#dot_dollar_field?(name) ⇒ true | false
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Does this field start with a dollar sign ($) or contain a dot/period (.)?
258 259 260 261 |
# File 'lib/mongoid/fields.rb', line 258 def dot_dollar_field?(name) n = aliased_fields[name] || name fields.key?(n) && (n.include?('.') || n.start_with?('$')) end |
#lazy_settable?(field, value) ⇒ true | false
Is the provided field a lazy evaluation?
235 236 237 |
# File 'lib/mongoid/fields.rb', line 235 def lazy_settable?(field, value) !frozen? && value.nil? && field.lazy? end |
#using_object_ids? ⇒ true | false
Refactored from using delegate for class load performance.
Is the document using object ids?
247 248 249 |
# File 'lib/mongoid/fields.rb', line 247 def using_object_ids? self.class.using_object_ids? end |
#validate_writable_field_name!(name) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Validate whether or not the field starts with a dollar sign ($) or contains a dot/period (.).
271 272 273 274 275 |
# File 'lib/mongoid/fields.rb', line 271 def validate_writable_field_name!(name) if dot_dollar_field?(name) raise Errors::InvalidDotDollarAssignment.new(self.class, name) end end |