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 11

attr_reader :_base, :_target, :_association

#_base (readonly)

[ GitHub ]

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

attr_reader :_base, :_target, :_association

#_target (readonly)

[ GitHub ]

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

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 121

def bind_foreign_key(keyed, id)
  unless keyed.frozen?
    try_method(keyed, _association.foreign_key_setter, id)
  end
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 183

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 169

def bind_inverse(doc, inverse)
  if doc.respond_to?(_association.inverse_setter) && !doc.frozen?
    try_method(doc, _association.inverse_setter, inverse)
  end
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 153

def bind_polymorphic_inverse_type(typed, name)
  if _association.inverse_type && !typed.frozen?
    try_method(typed, _association.inverse_type_setter, name)
  end
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 137

def bind_polymorphic_type(typed, name)
  if _association.type && !typed.frozen?
    try_method(typed, _association.type_setter, name)
  end
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 33

def binding
  unless _binding?
    _binding do
      yield(self) if block_given?
    end
  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 53

def check_inverse!(doc)
  unless _association.bindable?(doc)
    raise Errors::InverseNotFound.new(
        _base.class,
        _association.name,
        doc.class,
        _association.foreign_key
    )
  end
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 21

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

#record_id(_base) (private)

[ GitHub ]

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

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 67

def remove_associated(doc)
  if inverse = _association.inverse(doc)
    if _association.many?
      remove_associated_many(doc, inverse)
    elsif _association.in_to?
      remove_associated_in_to(doc, inverse)
    end
  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 103

def remove_associated_in_to(doc, inverse)
  # We only want to remove the inverse association when the inverse
  # document is in memory.
  if associated = doc.ivar(inverse)
    associated.send(_association.setter, nil)
  end
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 83

def remove_associated_many(doc, inverse)
  # We only want to remove the inverse association when the inverse
  # document is in memory.
  if 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
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 205

def set_base_association
  inverse_association = _association.inverse_association(_target)
  if inverse_association != _association && !inverse_association.nil?
    _base._association = inverse_association
  end
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:

  • method_name (String | Symbol)

    The method name.

  • *args (Object...)

    The arguments.

Returns:

  • (Object | nil)

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

[ GitHub ]

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

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 220

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