Class: Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy
- Inherits:
-
Mongoid::Association::Referenced::HasMany::Proxy
- Object
- Proxy
- Many
- Mongoid::Association::Referenced::HasMany::Proxy
- Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy
- Defined in:
- 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.
Instance Attribute Summary
Attributes inherited from Proxy
#_association, #_base, #_target
Class Method Summary collapse
-
.eager_loader(association, docs) ⇒ Object
Get the Eager object for this type of association.
-
.embedded? ⇒ false
Returns true if the association is an embedded one.
Instance Method Summary collapse
-
#<<(*args) ⇒ Array<Document>
(also: #push)
Appends a document or array of documents to the association.
-
#build(attributes = {}, type = nil) {|doc| ... } ⇒ Document
(also: #new)
Build a new document from the attributes and append it to this association without saving.
-
#concat(documents) ⇒ Array<Document>
Appends an array of documents to the association.
-
#delete(document) ⇒ Document
(also: #delete_one)
Delete the document from the association.
-
#nullify(replacement = []) ⇒ Object
(also: #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.
-
#substitute(replacement) ⇒ Many
Substitutes the supplied target documents for the existing documents in the association.
-
#unscoped ⇒ Criteria
Get a criteria for the documents without the default scoping applied.
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
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.
330 331 332 |
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 330 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.
341 342 343 |
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 341 def 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.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 27 def <<(*args) docs = args.flatten return concat(docs) if docs.size > 1 if doc = docs.first append(doc) do # We ignore the changes to the value for the foreign key in the # changed_attributes hash in this block of code for two reasons: # # 1) The add_to_set method deletes the value for the foreign # key in the changed_attributes hash, but if we enter this # method with a value for the foreign key in the # changed_attributes hash, then we want it to exist outside # this method as well. It's used later on in the Syncable # module to set the inverse foreign keys. # 2) The reset_unloaded method accesses the value for the foreign # key on _base, which causes it to get added to the # changed_attributes hash. This happens because when reading # a "resizable" attribute, it is automatically added to the # changed_attributes hash. This is true only for the foreign # key value for HABTM associations as the other associations # use strings for their foreign key values. For consistency # with the other associations, we ignore this addition to # the changed_attributes hash. # See MONGOID-4843 for a longer discussion about this. reset_foreign_key_changes do _base.add_to_set(foreign_key => doc.public_send(_association.primary_key)) if child_persistable?(doc) doc.save end reset_unloaded end 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.
107 108 109 110 111 112 113 114 115 116 |
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 107 def build(attributes = {}, type = nil) doc = Factory.execute_build(type || klass, attributes, execute_callbacks: false) append(doc) doc.apply_post_processed_defaults _base.public_send(foreign_key).push(doc.public_send(_association.primary_key)) unsynced(doc, inverse_foreign_key) yield(doc) if block_given? doc.run_pending_callbacks 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.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 75 def concat(documents) ids, docs, inserts = {}, [], [] documents.each do |doc| next unless doc append(doc) if persistable? || _creating? ids[doc.public_send(_association.primary_key)] = true save_or_delay(doc, docs, inserts) else existing = _base.public_send(foreign_key) unless existing.include?(doc.public_send(_association.primary_key)) existing.push(doc.public_send(_association.primary_key)) 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 Also known as: delete_one
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.
130 131 132 133 134 135 136 137 138 |
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 130 def delete(document) doc = super if doc && persistable? _base.pull(foreign_key => doc.public_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.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 152 def nullify(replacement = []) _target.each do |doc| execute_callback :before_remove, doc end unless _association.forced_nil_inverse? if field = _association.[:inverse_primary_key] ipk = _base.public_send(field) else ipk = _base._id end if replacement objects_to_clear = _base.public_send(foreign_key) - replacement.collect do |object| object.public_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.public_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 ])
204 205 206 207 208 209 210 211 212 213 |
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 204 def substitute(replacement) purge(replacement) unless replacement.blank? push(replacement.compact.uniq) else reset_unloaded clear_foreign_key_changes end self end |
#unscoped ⇒ Criteria
Get a criteria for the documents without the default scoping applied.
222 223 224 |
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 222 def unscoped klass.unscoped.any_in(_id: _base.public_send(foreign_key)) end |