Class: Mongoid::Association::Referenced::HasAndBelongsToMany::Proxy
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
ClassMethods ,
::Mongoid::Association::Referenced::HasMany::Proxy ,
::Mongoid::Association::Referenced::HasMany::Proxy::ClassMethods ,
Forwardable,
::Mongoid::Association::Many ,
Forwardable,
::Mongoid::Association::Proxy ,
Forwardable
|
|
Instance Chain:
|
|
Inherits: |
Mongoid::Association::Referenced::HasMany::Proxy
|
Defined in: | lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb |
Overview
Transparent proxy for has_and_belongs_to_many associations. An instance of this class is returned when calling the association getter method on the subject document. This class inherits from Mongoid::Association::Proxy and forwards most of its methods to the target of the association, i.e. the array of documents on the opposite-side collection which must be loaded.
Constant Summary
::Mongoid::Association::Proxy
- Inherited
Class Attribute Summary
ClassMethods
- Extended
embedded? | Returns true if the association is an embedded one. |
::Mongoid::Association::Referenced::HasMany::Proxy::ClassMethods
- Extended
embedded? | Returns true if the association is an embedded one. |
Class Method Summary
ClassMethods
- Extended
eager_loader | Get the |
::Mongoid::Association::Referenced::HasMany::Proxy
- Inherited
.new | Instantiate a new references_many association. |
::Mongoid::Association::Referenced::HasMany::Proxy::ClassMethods
- Extended
::Mongoid::Association::Proxy
- Inherited
.apply_ordering | Apply ordering to the criteria if it was defined on the association. |
.new | Sets the target and the association metadata properties. |
Instance Attribute Summary
::Mongoid::Association::Referenced::HasMany::Proxy
- Inherited
#persistable? | Are we able to persist this association? |
::Mongoid::Association::Many
- Inherited
::Mongoid::Association::Proxy
- Inherited
#_association, | |
#_base | Model instance for the base of the association. |
#_target | Model instance for one to one associations, or array of model instances for one to many associations, for the target of the association. |
::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
-
#<<(*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.
-
#clear(replacement = [])
Alias for #nullify.
-
#concat(documents) ⇒ Array<Document>
Appends an array of documents to the association.
-
#delete(document) ⇒ Document
(also: #delete_one)
Delete the document from the association.
-
#delete_one(document)
Alias for #delete.
-
#new(attributes = {}, type = nil)
Alias for #build.
-
#nullify(replacement = [])
(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.
-
#nullify_all(replacement = [])
Alias for #nullify.
-
#purge(replacement = [])
Alias for #nullify.
-
#push(*args)
Alias for #<<.
-
#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.
-
#append(document)
private
Appends the document to the target array, updating the index on the document at the same time.
-
#append_document(doc, ids, docs, inserts)
private
Processes a single document as part of a “concat“ command.
-
#binding ⇒ Binding
private
Instantiate the binding associated with this association.
-
#child_persistable?(doc) ⇒ true | false
private
Internal use only
Internal use only
Determine if the child document should be persisted.
-
#cleanup_inverse_for(replacement)
private
Does the cleanup for the inverse of the association when replacing the relation with another list of documents.
-
#clear_foreign_key_changes
private
Internal use only
Internal use only
Clears the foreign key from the changed_attributes hash.
-
#clear_target_for_nullify ⇒ Array<Document>
private
Clears the _target list and executes callbacks for each document.
-
#criteria(id_list = nil) ⇒ Criteria
private
Returns the criteria object for the target class with its documents set to target.
-
#inverse_primary_key ⇒ Object
private
The inverse primary key.
-
#reset_foreign_key_changes
private
Internal use only
Internal use only
Reset the value in the changed_attributes hash for the foreign key to its value before executing the given block.
-
#unsynced(doc, key) ⇒ true
private
Internal use only
Internal use only
Flag the base as unsynced with respect to the foreign key.
::Mongoid::Association::Referenced::HasMany::Proxy
- Inherited
#<< | Appends a document or array of documents to the association. |
#build | Build a new document from the attributes and append it to this association without saving. |
#clear | |
#concat | Appends an array of documents to the association. |
#delete | Delete the document from the association. |
#delete_all | Deletes all related documents from the database given the supplied conditions. |
#delete_one | |
#destroy_all | Destroys all related documents from the database given the supplied conditions. |
#each | Iterate over each document in the association and yield to the provided block. |
#exists? | Determine if any documents in this association exist in the database. |
#find | Find the matching document on the association, either based on id or conditions. |
#new | |
#nullify | 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. |
#nullify_all | |
#purge | Clear the association. |
#push | |
#substitute | Substitutes the supplied target documents for the existing documents in the association. |
#unscoped | Get a criteria for the documents without the default scoping applied. |
#already_related? | Whether the document and the base already have a persisted association. |
#append | Appends the document to the target array, updating the index on the document at the same time. |
#binding | Instantiate the binding associated with this association. |
#cascade! | Perform the necessary cascade operations for documents that just got deleted or nullified. |
#collection | Get the collection of the association in question. |
#criteria | Returns the criteria object for the target class with its documents set to target. |
#method_missing | If the target array does not respond to the supplied method then try to find a named scope or criteria on the class and send the call there. |
#persist_delayed | Persist all the delayed batch inserts. |
#remove_all | Deletes all related documents from the database given the supplied conditions. |
#remove_not_in | Remove all the documents in the proxy that do not have the provided ids. |
#save_or_delay | Save a persisted document immediately or delay a new document for batch insert. |
#update_or_delete_all | If the association is destructive, the matching documents will be removed. |
#with_add_callbacks | Execute before/after add callbacks around the block unless the objects already have a persisted association. |
::Mongoid::Association::Many
- Inherited
#cache_version | For compatibility with Rails’ caching. |
#create | Creates a new document on the references many association. |
#create! | Creates a new document on the references many association. |
#find_or_create_by | Find the first document given the conditions, or creates a new document with the conditions that were supplied. |
#find_or_create_by! | Find the first document given the conditions, or creates a new document with the conditions that were supplied. |
#find_or_initialize_by | Find the first |
#respond_to? | Since method_missing is overridden we should override this as well. |
#scoped | This is public access to the association’s criteria. |
#serializable_hash | Gets the document as a serializable hash, used by ActiveModel’s JSON and XML serializers. |
#unscoped | Get a criteria for the embedded documents without the default scoping applied. |
#_session, | |
#analyze_loaded_target | Return a 2-tuple of the number of elements in the relation, and the largest timestamp value. |
#analyze_unloaded_target | Returns a 2-tuple of the number of elements in the relation, and the largest timestamp value. |
#compute_cache_version | Computes the cache version for the relation using the given timestamp colum; see |
#find_or | Find the first object given the supplied attributes or create/initialize it. |
::Mongoid::Association::Proxy
- Inherited
#extend_proxies | Allow extension to be an array and extend each module. |
#extend_proxy, | |
#klass | Get the class from the association, or return nil if no association present. |
#reset_unloaded | Resets the criteria inside the association proxy. |
#substitutable | The default substitutable object for an association proxy is the clone of the target. |
::Mongoid::Association::Marshalable
- Included
#marshal_dump | Provides the data needed to Marshal.dump an association proxy. |
#marshal_load | Takes the provided data and sets it back on the proxy. |
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
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.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 58
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)) doc.save if child_persistable?(doc) reset_unloaded end end end unsynced(_base, foreign_key) and self end
#append(document) (private)
Appends the document to the target array, updating the index on the document at the same time.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 243
def append(document) execute_callbacks_around(:add, document) do _target.push(document) characterize_one(document) bind_one(document) yield if block_given? end end
#append_document(doc, ids, docs, inserts) (private)
Processes a single document as part of a “concat“ command.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 365
def append_document(doc, ids, docs, inserts) return unless doc append(doc) pk = doc.public_send(_association.primary_key) if persistable? || _creating? ids[pk] = true save_or_delay(doc, docs, inserts) else existing = _base.public_send(foreign_key) return if existing.include?(pk) existing.push(pk) unsynced(_base, foreign_key) end end
#binding ⇒ Binding (private)
Instantiate the binding associated with this association.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 258
def binding HasAndBelongsToMany::Binding.new(_base, _target, _association) 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.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 123
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
#child_persistable?(doc) ⇒ true
| false
(private)
Determine if the child document should be persisted.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 272
def child_persistable?(doc) (persistable? || _creating?) && !(doc.persisted? && _association.forced_nil_inverse?) end
#cleanup_inverse_for(replacement) (private)
Does the cleanup for the inverse of the association when replacing the relation with another list of documents.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 309
def cleanup_inverse_for(replacement) if replacement new_ids = replacement.collect { |doc| doc.public_send(_association.primary_key) } objects_to_clear = _base.public_send(foreign_key) - new_ids criteria(objects_to_clear).pull(inverse_foreign_key => inverse_primary_key) else criteria.pull(inverse_foreign_key => inverse_primary_key) end end
#clear(replacement = [])
Alias for #nullify.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 176
alias clear nullify
#clear_foreign_key_changes (private)
Clears the foreign key from the changed_attributes hash.
This is, in general, used to clear the foreign key from the changed_attributes hash for consistency with the other referenced associations.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 220
def clear_foreign_key_changes _base.changed_attributes.delete(foreign_key) end
#clear_target_for_nullify ⇒ Array<Document> (private)
Clears the _target list and executes callbacks for each document. If an exception occurs in an after_remove hook, the exception is saved, the processing completes, and then the exception is re-raised.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 336
def clear_target_for_nullify after_remove_error = nil many_to_many = _target.clear do |doc| unbind_one(doc) doc.changed_attributes.delete(inverse_foreign_key) unless _association.forced_nil_inverse? begin execute_callback :after_remove, doc rescue StandardError => e after_remove_error = e end end raise after_remove_error if after_remove_error many_to_many 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.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 105
def concat(documents) ids, docs, inserts = {}, [], [] documents.each { |doc| append_document(doc, ids, docs, inserts) } _base.push(foreign_key => ids.keys) if persistable? || _creating? persist_delayed(docs, inserts) self end
#criteria(id_list = nil) ⇒ Criteria (private)
Returns the criteria object for the target class with its documents set to target.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 284
def criteria(id_list = nil) _association.criteria(_base, id_list) 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.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 146
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
#delete_one(document)
Alias for #delete.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 158
alias delete_one delete
#inverse_primary_key ⇒ Object
(private)
The inverse primary key
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 322
def inverse_primary_key if (field = _association. [:inverse_primary_key]) _base.public_send(field) else _base._id end end
#new(attributes = {}, type = nil)
Alias for #build.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 134
alias new build
#nullify(replacement = []) 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.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 168
def nullify(replacement = []) _target.each { |doc| execute_callback :before_remove, doc } cleanup_inverse_for(replacement) unless _association.forced_nil_inverse? _base.set(foreign_key => _base.public_send(foreign_key).clear) if persistable? clear_target_for_nullify end
#nullify_all(replacement = [])
Alias for #nullify.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 175
alias nullify_all nullify
#purge(replacement = [])
Alias for #nullify.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 177
alias purge nullify
#push(*args)
Alias for #<<.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 94
alias push <<
#reset_foreign_key_changes (private)
Reset the value in the changed_attributes hash for the foreign key to its value before executing the given block.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 228
def reset_foreign_key_changes prior_fk_change = _base.changed_attributes.key?(foreign_key) fk = _base.changed_attributes[foreign_key].dup yield if block_given? _base.changed_attributes[foreign_key] = fk clear_foreign_key_changes unless prior_fk_change 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 ])
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 189
def substitute(replacement) purge(replacement) if replacement.blank? reset_unloaded clear_foreign_key_changes else push(replacement.compact.uniq) end self end
#unscoped ⇒ Criteria
Get a criteria for the documents without the default scoping applied.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 207
def unscoped klass.unscoped.any_in(_id: _base.public_send(foreign_key)) end
#unsynced(doc, key) ⇒ true
(private)
Flag the base as unsynced with respect to the foreign key.
# File 'lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb', line 299
def unsynced(doc, key) doc._synced[key] = false true end