Module: Mongoid::Persistable::Settable
- Extended by:
- ActiveSupport::Concern
- Included in:
- Mongoid::Persistable
- Defined in:
- lib/mongoid/persistable/settable.rb
Overview
Defines behavior for $set operations.
Instance Method Summary collapse
-
#set(setters) ⇒ Document
Perform a $set operation on the provided field/value pairs and set the values in the document in memory.
Instance Method Details
#set(setters) ⇒ Document
Perform a $set operation on the provided field/value pairs and set the values in the document in memory.
The key can be a dotted sequence of keys, in which case the top level field is treated as a nested hash and any missing keys are created automatically:
Performing a nested set like this merges values of intermediate keys:
If the top level field was not a hash, its original value is discarded and the field is replaced with a hash.
Note that unlike MongoDB’s $set, Mongoid’s set writes out the entire field even when setting a subset of the field via the nested hash semantics. This means performing a $set with nested hash semantics can overwrite other hash keys within the top level field in the database.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/mongoid/persistable/settable.rb', line 48 def set(setters) prepare_atomic_operation do |ops| process_atomic_operations(setters) do |field, value| field_seq = field.to_s.split('.') field = field_seq.shift if field_seq.length > 0 # nested hash path old_value = attributes[field] # if the old value is not a hash, clobber it unless Hash === old_value old_value = {} end # descend into the hash, creating intermediate keys as needed cur_value = old_value while field_seq.length > 1 cur_key = field_seq.shift # clobber on each level if type is not a hash unless Hash === cur_value[cur_key] cur_value[cur_key] = {} end cur_value = cur_value[cur_key] end # now we are on the leaf level, perform the set # and overwrite whatever was on this level before cur_value[field_seq.shift] = value # and set value to the value of the top level field # because this is what we pass to $set value = old_value end process_attribute(field, value) unless relations.include?(field.to_s) ops[atomic_attribute_name(field)] = attributes[field] end end { "$set" => ops } unless ops.empty? end end |