123456789_123456789_123456789_123456789_123456789_

Module: Mongoid::Association::Bindable

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Included In:
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
Defined in: lib/mongoid/association/bindable.rb

Overview

Superclass for all objects that bind associations together.

Instance Attribute Summary

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

Instance Attribute Details

#_association (readonly)

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 9

attr_reader :_base, :_target, :_association

#_base (readonly)

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 9

attr_reader :_base, :_target, :_association

#_target (readonly)

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 9

attr_reader :_base, :_target, :_association

Instance Method Details

#bind_foreign_key(keyed, id) (private)

This method is for internal use only.

::Set the id of the related document in the foreign key field on the keyed document.

Examples:

Bind the foreign key.

binding.bind_foreign_key(post, person._id)

Parameters:

  • keyed (Document)

    The document that stores the foreign key.

  • id (Object)

    The id of the bound document.

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 119

def bind_foreign_key(keyed, id)
  return if keyed.frozen?

  try_method(keyed, _association.foreign_key_setter, id)
end

#bind_from_relational_parent(doc) (private)

This method is for internal use only.

Bind the provided document with the base from the parent association.

Examples:

Bind the document with the base.

binding.bind_from_relational_parent(doc)

Parameters:

  • doc (Document)

    The document to bind.

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 181

def bind_from_relational_parent(doc)
  check_inverse!(doc)
  remove_associated(doc)
  bind_foreign_key(doc, record_id(_base))
  bind_polymorphic_type(doc, _base.class.name)
  bind_inverse(doc, _base)
end

#bind_inverse(doc, inverse) (private)

This method is for internal use only.

Bind the inverse document to the child document so that the in memory instances are the same.

Examples:

Bind the inverse.

binding.bind_inverse(post, person)

Parameters:

  • doc (Document)

    The base document.

  • inverse (Document)

    The inverse document.

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 167

def bind_inverse(doc, inverse)
  return unless doc.respond_to?(_association.inverse_setter) && !doc.frozen?

  try_method(doc, _association.inverse_setter, inverse)
end

#bind_polymorphic_inverse_type(typed, name) (private)

This method is for internal use only.

::Set the type of the related document on the foreign type field, used when associations are polymorphic.

Examples:

Bind the polymorphic type.

binding.bind_polymorphic_inverse_type(post, "Person")

Parameters:

  • typed (Document)

    The document that stores the type field.

  • name (String)

    The name of the model.

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 151

def bind_polymorphic_inverse_type(typed, name)
  return unless _association.inverse_type && !typed.frozen?

  try_method(typed, _association.inverse_type_setter, name)
end

#bind_polymorphic_type(typed, name) (private)

This method is for internal use only.

::Set the type of the related document on the foreign type field, used when associations are polymorphic.

Examples:

Bind the polymorphic type.

binding.bind_polymorphic_type(post, "Person")

Parameters:

  • typed (Document)

    The document that stores the type field.

  • name (String)

    The name of the model.

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 135

def bind_polymorphic_type(typed, name)
  return unless _association.type && !typed.frozen?

  try_method(typed, _association.type_setter, name)
end

#bindingObject

Execute the provided block inside a binding.

Examples:

Execute the binding block.

binding.binding do
  base.foreign_key = 1
end

Returns:

  • (Object)

    The result of the yield.

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 31

def binding
  return if _binding?

  _binding do
    yield(self) if block_given?
  end
end

#check_inverse!(doc) (private)

This method is for internal use only.

Check if the inverse is properly defined.

Examples:

Check the inverse definition.

binding.check_inverse!(doc)

Parameters:

  • doc (Document)

    The document getting bound.

Raises:

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 51

def check_inverse!(doc)
  return if _association.bindable?(doc)

  raise Errors::InverseNotFound.new(
    _base.class,
    _association.name,
    doc.class,
    _association.foreign_key
  )
end

#initialize(base, target, association)

Create the new binding.

Examples:

Initialize a binding.

Binding.new(base, target, association)

Parameters:

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 19

def initialize(base, target, association)
  @_base, @_target, @_association = base, target, association
end

#record_id(_base) (private)

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 189

def record_id(_base)
  _base.__send__(_association.primary_key)
end

#remove_associated(doc) (private)

Remove the associated document from the inverse’s association.

Parameters:

  • doc (Document)

    The document to remove.

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 65

def remove_associated(doc)
  return unless inverse = _association.inverse(doc)

  if _association.many?
    remove_associated_many(doc, inverse)
  elsif _association.in_to?
    remove_associated_in_to(doc, inverse)
  end
end

#remove_associated_in_to(doc, inverse) (private)

Remove the associated document from the inverse’s association.

This method removes associated on belongs_to and embedded_in associations.

Parameters:

  • doc (Document)

    The document to remove.

  • inverse (Symbol)

    The name of the inverse.

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 101

def remove_associated_in_to(doc, inverse)
  # We only want to remove the inverse association when the inverse
  # document is in memory.
  return unless associated = doc.ivar(inverse)

  associated.send(_association.setter, nil)
end

#remove_associated_many(doc, inverse) (private)

Remove the associated document from the inverse’s association.

This method removes the associated on *_many relationships.

Parameters:

  • doc (Document)

    The document to remove.

  • inverse (Symbol)

    The name of the inverse.

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 81

def remove_associated_many(doc, inverse)
  # We only want to remove the inverse association when the inverse
  # document is in memory.
  return unless inv = doc.ivar(inverse)

  # This first condition is needed because when assigning the
  # embeds_many association using the same embeds_many
  # association, we delete from the array we are about to assign.
  if _base != inv && (associated = inv.ivar(_association.name))
    associated.delete(doc)
  end
end

#set_base_associationtrue | false (private)

This method is for internal use only.

Ensure that the association on the base is correct, for the cases where we have multiple belongs to definitions and were are setting different parents in memory in order.

Examples:

::Set the base association.

binding.set_base_association

Returns:

  • (true | false)

    If the association changed.

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 203

def set_base_association
  inverse_association = _association.inverse_association(_target)
  return unless inverse_association != _association && !inverse_association.nil?

  _base._association = inverse_association
end

#try_method(object, method_name, *args) ⇒ Object | nil (private)

Convenience method to perform #try but return nil if the method argument is nil.

Examples:

Call method if it exists.

object.try_method(:use, "The Force")

Return nil if method argument is nil.

object.try_method(nil, "The Force") #=> nil

Parameters:

Returns:

  • (Object | nil)

    The result of the try or nil if the method does not exist.

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 239

def try_method(object, method_name, *args)
  object.try(method_name, *args) if method_name
end

#unbind_from_relational_parent(doc) (private)

This method is for internal use only.

Bind the provided document with the base from the parent association.

Examples:

Bind the document with the base.

unbinding.unbind_from_relational_parent(doc)

Parameters:

  • doc (Document)

    The document to unbind.

[ GitHub ]

  
# File 'lib/mongoid/association/bindable.rb', line 218

def unbind_from_relational_parent(doc)
  check_inverse!(doc)
  bind_foreign_key(doc, nil)
  bind_polymorphic_type(doc, nil)
  bind_inverse(doc, nil)
end