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

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

Overview

This class defines the behavior for all associations 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



298
299
300
# File 'build/mongoid-7.3/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 298

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

.embedded?false

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

Examples:

Is this association embedded?

Referenced::ManyToMany.embedded?

Returns:

  • (false)

    Always false.

Since:

  • 2.0.0.rc.1



311
312
313
# File 'build/mongoid-7.3/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 311

def embedded?
  false
end

Instance Method Details

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

Appends a document or array of documents to the association. 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



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

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 association without saving.

Examples:

Build a new document on the association.

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



90
91
92
93
94
95
96
97
98
# File 'build/mongoid-7.3/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 90

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



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

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 association. This will set the foreign key on the document to nil. If the dependent options on the association are :delete_all 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



114
115
116
117
118
119
120
121
122
# File 'build/mongoid-7.3/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 114

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

person.preferences.nullify

Parameters:

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

    The replacement documents.

Since:

  • 2.0.0.rc.1



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
164
165
166
167
168
169
170
# File 'build/mongoid-7.3/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 134

def nullify(replacement = [])
  _target.each do |doc|
    execute_callback :before_remove, doc
  end
  unless _association.forced_nil_inverse?
    if field = _association.options[:inverse_primary_key]
      ipk = _base.send(field)
    else
      ipk = _base._id
    end
    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 => ipk)
    else
      criteria.pull(inverse_foreign_key => ipk)
    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 association. If the new target is nil, perform the necessary deletion.

person.preferences.substitute([ new_post ])

Examples:

Replace the association.

Parameters:

  • replacement (Array<Document>)

    The replacement target.

Returns:

  • (Many)

    The association.

Since:

  • 2.0.0.rc.1



188
189
190
191
192
193
194
195
196
# File 'build/mongoid-7.3/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 188

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



207
208
209
# File 'build/mongoid-7.3/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 207

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