Class: Mongoid::Association::Embedded::EmbedsOne::Proxy
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
::Mongoid::Association::One ,
::Mongoid::Association::Proxy ,
Forwardable
|
|
Instance Chain:
|
|
Inherits: |
Mongoid::Association::One
|
Defined in: | lib/mongoid/association/embedded/embeds_one/proxy.rb |
Overview
Transparent proxy for embeds_one associations. An instance of this class is returned when calling the association getter method on the parent document. This class inherits from Mongoid::Association::Proxy and forwards most of its methods to the target of the association, i.e. the child document.
Constant Summary
-
VALID_OPTIONS =
The valid options when defining this association.
%i[ autobuild as cascade_callbacks cyclic store_as ].freeze
::Mongoid::Association::Proxy
- Inherited
Class Attribute Summary
-
.embedded? ⇒ true
readonly
Returns true if the association is an embedded one.
Class Method Summary
-
.eager_loader(associations, docs) ⇒ Mongoid::Association::Embedded::Eager
Returns the eager loader for this association.
-
.new(base, target, association) ⇒ Proxy
constructor
Instantiate a new embeds_one association.
-
.path(document) ⇒ Mongoid::Atomic::Paths::Embedded::One
Get the path calculator for the supplied document.
::Mongoid::Association::Proxy
- Inherited
.apply_ordering | Apply ordering to the criteria if it was defined on the association. |
.new | Sets the target and the association metadata properties. |
Instance Attribute Summary
-
#persistable? ⇒ true | false
readonly
private
Are we able to persist this association?
::Mongoid::Association::Proxy
- Inherited
#_association, | |
#_base | Model instance for the base of the association. |
#_target | Model instance for one to one associations, or array of model instances for one to many associations, for the target of the association. |
::Mongoid::Threaded::Lifecycle
- Included
#_assigning | Begin the assignment of attributes. |
#_assigning? | Is the current thread in assigning mode? |
#_binding | Execute a block in binding mode. |
#_binding? | Is the current thread in binding mode? |
#_building | Execute a block in building mode. |
#_building? | Is the current thread in building mode? |
#_creating? | Is the current thread in creating mode? |
#_loading | Execute a block in loading mode. |
#_loading? | Is the current thread in loading mode? |
Instance Method Summary
-
#substitute(replacement) ⇒ Document | nil
Substitutes the supplied target documents for the existing document in the association.
-
#binding ⇒ Binding
private
Instantiate the binding associated with this association.
-
#replace_with(replacement)
private
Replaces the current document with the given replacement document, which may be a
::Hash
of attributes. -
#replace_with_nil_document(replacement) ⇒ true | false
private
Checks the argument.
-
#update_attributes_hash(replacement)
private
Internal use only
Internal use only
Update the _base’s attributes hash with the _target’s attributes.
-
#update_target_when_not_assigning(replacement)
private
When not “_assigning?“, the target may need to be destroyed, and may need to be marked as a new record.
::Mongoid::Association::One
- Inherited
#__evolve_object_id__ | Evolve the proxy document into an object id. |
#clear | Clear this relation - same as calling #delete on the document. |
#in_memory | Get all the documents in the relation that are loaded into memory. |
#respond_to? | Since method_missing is overridden we should override this as well. |
::Mongoid::Association::Proxy
- Inherited
#extend_proxies | Allow extension to be an array and extend each module. |
#extend_proxy, | |
#klass | Get the class from the association, or return nil if no association present. |
#reset_unloaded | Resets the criteria inside the association proxy. |
#substitutable | The default substitutable object for an association proxy is the clone of the target. |
::Mongoid::Association::Marshalable
- Included
#marshal_dump | Provides the data needed to Marshal.dump an association proxy. |
#marshal_load | Takes the provided data and sets it back on the proxy. |
Constructor Details
.new(base, target, association) ⇒ Proxy
Instantiate a new embeds_one association.
# File 'lib/mongoid/association/embedded/embeds_one/proxy.rb', line 33
def initialize(base, target, association) super do characterize_one(_target) bind_one characterize_one(_target) update_attributes_hash(_target) _base._reset_memoized_descendants! _target.save if persistable? end end
Class Attribute Details
.embedded? ⇒ true
(readonly)
Returns true if the association is an embedded one. In this case always true.
# File 'lib/mongoid/association/embedded/embeds_one/proxy.rb', line 201
def true end
Class Method Details
.eager_loader(associations, docs) ⇒ Mongoid::Association::Embedded::Eager
Returns the eager loader for this association.
.path(document) ⇒ Mongoid::Atomic::Paths::Embedded::One
Get the path calculator for the supplied document.
Instance Attribute Details
#persistable? ⇒ true
| false
(readonly, private)
Are we able to persist this association?
# File 'lib/mongoid/association/embedded/embeds_one/proxy.rb', line 89
def persistable? _base.persisted? && !_binding? && !_building? && !_assigning? end
Instance Method Details
#binding ⇒ Binding (private)
Instantiate the binding associated with this association.
#replace_with(replacement) (private)
Replaces the current document with the given replacement document, which may be a ::Hash
of attributes.
# File 'lib/mongoid/association/embedded/embeds_one/proxy.rb', line 171
def replace_with(replacement) replacement = Factory.build(klass, replacement) if replacement.is_a?(::Hash) self._target = replacement characterize_one(_target) bind_one update_attributes_hash(_target) _target.save if persistable? end
#replace_with_nil_document(replacement) ⇒ true
| false
(private)
Checks the argument. If it is non-nil, this method does nothing. Otherwise, it performs the logic for replacing the current document with nil.
# File 'lib/mongoid/association/embedded/embeds_one/proxy.rb', line 150
def replace_with_nil_document(replacement) return false if replacement update_attributes_hash(replacement) # when `touch: true` is the default (see MONGOID-5016), creating # an embedded document will touch the parent, and will cause the # _descendants list to be initialized and memoized. If the object # is then deleted, we need to make sure and un-memoize that list, # otherwise when the update happens, the memoized _descendants list # gets used and the "deleted" subdocument gets added again. _reset_memoized_descendants! true end
#substitute(replacement) ⇒ Document | nil
Substitutes the supplied target documents for the existing document in the association.
# File 'lib/mongoid/association/embedded/embeds_one/proxy.rb', line 53
def substitute(replacement) return self if replacement == self if _assigning? _base.add_atomic_unset(_target) unless replacement else update_target_when_not_assigning(replacement) end unbind_one return nil if replace_with_nil_document(replacement) replace_with(replacement) self end
#update_attributes_hash(replacement) (private)
Update the _base’s attributes hash with the _target’s attributes
#update_target_when_not_assigning(replacement) (private)
When not “_assigning?“, the target may need to be destroyed, and may need to be marked as a new record. This method takes care of that, with extensive documentation for why it is necessary.
# File 'lib/mongoid/association/embedded/embeds_one/proxy.rb', line 112
def update_target_when_not_assigning(replacement) # The associated object will be replaced by the below update if non-nil, so only # run the callbacks and state-changing code by passing persist: false in that case. _target.destroy(persist: !replacement) if persistable? # A little explanation on why this is needed... Say we have three assignments: # # canvas.palette = palette # canvas.palette = nil # canvas.palette = palette # Where canvas embeds_one palette. # # Previously, what was happening was, on the first assignment, # palette was considered a "new record" (new_record?=true) and # thus palette was being inserted into the database. However, # on the third assignment, we're trying to reassign the palette, # palette is no longer considered a new record, because it had # been inserted previously. This is not exactly accurate, # because the second assignment ultimately removed the palette # from the database, so it needs to be reinserted. Since the # palette's new_record is false, Mongoid ends up "updating" the # document, which doesn't reinsert it into the database. # # The change I introduce here, respecifies palette as a "new # record" when it gets removed from the database, so if it is # reassigned, it will be reinserted into the database. _target.new_record = true end