Class: Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy

Inherits:
Mongoid::Association::Referenced::HasMany::Proxy show all
Defined in:
build/mongoid-7.0/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb

Overview

This class defines the behaviour for all relations that are a many-to-many between documents in different collections.

Since:

  • 7.0

Instance Attribute Summary

Attributes inherited from Proxy

#_association, #_base, #_target

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Mongoid::Association::Referenced::HasMany::Proxy

#delete_all, #destroy_all, #each, #exists?, #find, #initialize

Methods inherited from Many

#blank?, #create, #create!, #find_or_create_by, #find_or_create_by!, #find_or_initialize_by, #nil?, #respond_to?, #scoped, #serializable_hash

Methods inherited from Proxy

apply_ordering, #extend_proxies, #init, #klass, #reset_unloaded, #substitutable

Methods included from Marshalable

#marshal_dump, #marshal_load

Constructor Details

This class inherits a constructor from Mongoid::Association::Referenced::HasMany::Proxy

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Mongoid::Association::Referenced::HasMany::Proxy

Class Method Details

.eager_loader(association, docs) ⇒ Object

Get the Eager object for this type of association.

Examples:

Get the eager loader object

Parameters:

  • association (Association)

    The association object.

  • docs (Array<Document>)

    The array of documents.

Since:

  • 7.0



291
292
293
# File 'build/mongoid-7.0/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 291

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

.embedded?false

Returns true if the relation is an embedded one. In this case always false.

Examples:

Is this relation embedded?

Referenced::ManyToMany.embedded?

Returns:

  • (false)

    Always false.

Since:

  • 2.0.0.rc.1



304
305
306
# File 'build/mongoid-7.0/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 304

def embedded?
  false
end

Instance Method Details

#<<(*args) ⇒ Array<Document> Also known as: push

Appends a document or array of documents to the relation. Will set the parent and update the index in the process.

Examples:

Append a document.

person.posts << post

Push a document.

person.posts.push(post)

Concat with other documents.

person.posts.concat([ post_one, post_two ])

Parameters:

Returns:

  • (Array<Document>)

    The loaded docs.

Since:

  • 2.0.0.beta.1



28
29
30
31
32
33
34
35
36
37
38
39
# File 'build/mongoid-7.0/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 28

def <<(*args)
  docs = args.flatten
  return concat(docs) if docs.size > 1
  if doc = docs.first
    append(doc)
    _base.add_to_set(foreign_key => doc.send(_association.primary_key))
    if child_persistable?(doc)
      doc.save
    end
  end
  unsynced(_base, foreign_key) and self
end

#build(attributes = {}, type = nil) {|doc| ... } ⇒ Document Also known as: new

Build a new document from the attributes and append it to this relation without saving.

Examples:

Build a new document on the relation.

person.posts.build(:title => "A new post")

Parameters:

  • attributes (Hash) (defaults to: {})

    The attributes of the new document.

  • type (Class) (defaults to: nil)

    The optional subclass to build.

Yields:

  • (doc)

Returns:

Since:

  • 2.0.0.beta.1



88
89
90
91
92
93
94
95
96
# File 'build/mongoid-7.0/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 88

def build(attributes = {}, type = nil)
  doc = Factory.build(type || klass, attributes)
  _base.send(foreign_key).push(doc._id)
  append(doc)
  doc.apply_post_processed_defaults
  unsynced(doc, inverse_foreign_key)
  yield(doc) if block_given?
  doc
end

#concat(documents) ⇒ Array<Document>

Appends an array of documents to the relation. Performs a batch insert of the documents instead of persisting one at a time.

Examples:

Concat with other documents.

person.posts.concat([ post_one, post_two ])

Parameters:

  • documents (Array<Document>)

    The docs to add.

Returns:

Since:

  • 2.4.0



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'build/mongoid-7.0/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 54

def concat(documents)
  ids, docs, inserts = {}, [], []
  documents.each do |doc|
    next unless doc
    append(doc)
    if persistable? || _creating?
      ids[doc._id] = true
      save_or_delay(doc, docs, inserts)
    else
      existing = _base.send(foreign_key)
      unless existing.include?(doc._id)
        existing.push(doc._id) and unsynced(_base, foreign_key)
      end
    end
  end
  if persistable? || _creating?
    _base.push(foreign_key => ids.keys)
  end
  persist_delayed(docs, inserts)
  self
end

#delete(document) ⇒ Document

Delete the document from the relation. This will set the foreign key on the document to nil. If the dependent options on the relation are :delete or :destroy the appropriate removal will occur.

Examples:

Delete the document.

person.posts.delete(post)

Parameters:

  • document (Document)

    The document to remove.

Returns:

Since:

  • 2.1.0



112
113
114
115
116
117
118
119
120
# File 'build/mongoid-7.0/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 112

def delete(document)
  doc = super
  if doc && persistable?
    _base.pull(foreign_key => doc.send(_association.primary_key))
    _target._unloaded = criteria
    unsynced(_base, foreign_key)
  end
  doc
end

#nullify(replacement = []) ⇒ Object Also known as: nullify_all, clear, purge

Removes all associations between the base document and the target documents by deleting the foreign keys and the references, orphaning the target documents in the process.

Examples:

Nullify the relation.

person.preferences.nullify

Parameters:

  • replacement (Array<Document>) (defaults to: [])

    The replacement documents.

Since:

  • 2.0.0.rc.1



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'build/mongoid-7.0/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 132

def nullify(replacement = [])
  _target.each do |doc|
    execute_callback :before_remove, doc
  end
  unless _association.forced_nil_inverse?
    if replacement
      objects_to_clear = _base.send(foreign_key) - replacement.collect do |object|
        object.send(_association.primary_key)
      end
      criteria(objects_to_clear).pull(inverse_foreign_key => _base._id)
    else
      criteria.pull(inverse_foreign_key => _base._id)
    end
  end
  if persistable?
    _base.set(foreign_key => _base.send(foreign_key).clear)
  end
  after_remove_error = nil
  many_to_many = _target.clear do |doc|
    unbind_one(doc)
    unless _association.forced_nil_inverse?
      doc.changed_attributes.delete(inverse_foreign_key)
    end
    begin
      execute_callback :after_remove, doc
    rescue => e
      after_remove_error = e
    end
  end
  raise after_remove_error if after_remove_error
  many_to_many
end

#substitute(replacement) ⇒ Many

Substitutes the supplied target documents for the existing documents in the relation. If the new target is nil, perform the necessary deletion.

person.preferences.substitute([ new_post ])

Examples:

Replace the relation.

Parameters:

  • replacement (Array<Document>)

    The replacement target.

Returns:

  • (Many)

    The relation.

Since:

  • 2.0.0.rc.1



181
182
183
184
185
186
187
188
189
# File 'build/mongoid-7.0/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 181

def substitute(replacement)
  purge(replacement)
  unless replacement.blank?
    push(replacement.compact.uniq)
  else
    reset_unloaded
  end
  self
end

#unscopedCriteria

Get a criteria for the documents without the default scoping applied.

Examples:

Get the unscoped criteria.

person.preferences.unscoped

Returns:

Since:

  • 2.4.0



200
201
202
# File 'build/mongoid-7.0/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 200

def unscoped
  klass.unscoped.any_in(_id: _base.send(foreign_key))
end