123456789_123456789_123456789_123456789_123456789_

Class: Mongoid::Association::Embedded::EmbedsOne::Proxy

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
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

::Mongoid::Association::Proxy - Inherited

KEEPER_METHODS

Class Attribute Summary

Class Method Summary

::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

::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

::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.

Examples:

Create the new proxy.

One.new(person, name, association)

Parameters:

[ GitHub ]

  
# 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.

Examples:

Is this association embedded?

Association::Embedded::EmbedsOne.embedded?

Returns:

  • (true)

    true.

[ GitHub ]

  
# File 'lib/mongoid/association/embedded/embeds_one/proxy.rb', line 201

def embedded?
  true
end

Class Method Details

.eager_loader(associations, docs) ⇒ Mongoid::Association::Embedded::Eager

Returns the eager loader for this association.

Parameters:

  • associations (Array<Mongoid::Association>)

    The associations to be eager loaded

  • docs (Array<Mongoid::Document>)

    The parent documents that possess the given associations, which ought to be populated by the eager-loaded documents.

[ GitHub ]

  
# File 'lib/mongoid/association/embedded/embeds_one/proxy.rb', line 190

def eager_loader(associations, docs)
  Eager.new(associations, docs)
end

.path(document) ⇒ Mongoid::Atomic::Paths::Embedded::One

Get the path calculator for the supplied document.

Examples:

Get the path calculator.

Proxy.path(document)

Parameters:

  • document (Document)

    The document to calculate on.

Returns:

[ GitHub ]

  
# File 'lib/mongoid/association/embedded/embeds_one/proxy.rb', line 214

def path(document)
  Mongoid::Atomic::Paths::Embedded::One.new(document)
end

Instance Attribute Details

#persistable?true | false (readonly, private)

Are we able to persist this association?

Examples:

Can we persist the association?

relation.persistable?

Returns:

  • (true | false)

    If the association is persistable.

[ GitHub ]

  
# File 'lib/mongoid/association/embedded/embeds_one/proxy.rb', line 89

def persistable?
  _base.persisted? && !_binding? && !_building? && !_assigning?
end

Instance Method Details

#bindingBinding (private)

Instantiate the binding associated with this association.

Examples:

Get the binding.

relation.binding([ address ])

Returns:

  • (Binding)

    The association’s binding.

[ GitHub ]

  
# File 'lib/mongoid/association/embedded/embeds_one/proxy.rb', line 79

def binding
  Binding.new(_base, _target, _association)
end

#replace_with(replacement) (private)

Replaces the current document with the given replacement document, which may be a ::Hash of attributes.

Parameters:

  • replacement (Mongoid::Document | Hash)

    the document to substitute in place of the current document.

[ GitHub ]

  
# 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.

Parameters:

Returns:

  • (true | false)

    whether a nil document was substituted or not.

[ GitHub ]

  
# 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.

Examples:

Substitute the new document.

person.name.substitute(new_name)

Parameters:

  • replacement (Document | Hash)

    A document to replace the target.

Returns:

  • (Document | nil)

    The association or nil.

[ GitHub ]

  
# 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)

This method is for internal use only.

Update the _base’s attributes hash with the _target’s attributes

Parameters:

  • replacement (Document | nil)

    The doc to use to update the attributes hash.

[ GitHub ]

  
# File 'lib/mongoid/association/embedded/embeds_one/proxy.rb', line 99

def update_attributes_hash(replacement)
  if replacement
    _base.attributes.merge!(_association.store_as => replacement.attributes)
  else
    _base.attributes.delete(_association.store_as)
  end
end

#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.

Parameters:

[ GitHub ]

  
# 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