Class: Mongoid::Association::Nested::Many
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Instance Chain:
self,
Buildable
|
|
Inherits: | Object |
Defined in: | lib/mongoid/association/nested/many.rb |
Overview
Builder class used to perform #accepts_nested_attributes_for attribute assignment on many-to-n associations.
Class Method Summary
-
.new(association, attributes, options = {}) ⇒ Many
constructor
Create the new builder for nested attributes on one-to-many associations.
Instance Attribute Summary
Buildable
- Included
#allow_destroy? | Determines if destroys are allowed for this document. |
#association, #attributes, #existing, #options, | |
#update_only? | Determines if only updates can occur. |
Instance Method Summary
-
#build(parent, options = {}) ⇒ Array
Builds the association depending on the attributes and the options passed to the macro.
-
#destroy(parent, relation, doc)
private
Internal use only
Internal use only
Destroy the child document, needs to do some checking for embedded associations and delay the destroy in case parent validation fails.
-
#destroy_document(relation, doc)
private
Internal use only
Internal use only
Destroy the document.
-
#destroyable?(attributes) ⇒ true | false
private
Can the existing association potentially be deleted?
-
#over_limit?(attributes) ⇒ true | false
private
Are the supplied attributes of greater number than the supplied limit?
-
#process_attributes(parent, attrs)
private
Internal use only
Internal use only
Process each set of attributes one at a time for each potential new, existing, or ignored document.
-
#update_document(doc, attrs)
private
Internal use only
Internal use only
Update the document.
-
#update_nested_relation(parent, id, attrs)
private
Internal use only
Internal use only
Update nested association.
Buildable
- Included
#convert_id | Convert an id to its appropriate type. |
#reject? | Returns the reject if option defined with the macro. |
#delete_id | Deletes the id key from the given hash. |
#extract_id | Get the id attribute from the given hash, whether it’s prefixed with an underscore or is a symbol. |
Constructor Details
.new(association, attributes, options = {}) ⇒ Many
Create the new builder for nested attributes on one-to-many associations.
# File 'lib/mongoid/association/nested/many.rb', line 50
def initialize(association, attributes, = {}) if attributes.respond_to?(:with_indifferent_access) @attributes = attributes.with_indifferent_access.sort do |a, b| a[0].to_i <=> b[0].to_i end else @attributes = attributes end @association = association @options = @class_name = [:class_name] ? [:class_name].constantize : association.klass end
Instance Method Details
#build(parent, options = {}) ⇒ Array
Builds the association depending on the attributes and the options passed to the macro.
This attempts to perform 3 operations, either one of an update of the existing association, a replacement of the association with a new document, or a removal of the association.
# File 'lib/mongoid/association/nested/many.rb', line 27
def build(parent, = {}) @existing = parent.send(association.name) if over_limit?(attributes) raise Errors::TooManyNestedAttributeRecords.new(existing, [:limit]) end attributes.each do |attrs| if attrs.is_a?(::Hash) process_attributes(parent, attrs.with_indifferent_access) else process_attributes(parent, attrs[1].with_indifferent_access) end end end
#destroy(parent, relation, doc) (private)
Destroy the child document, needs to do some checking for embedded associations and delay the destroy in case parent validation fails.
# File 'lib/mongoid/association/nested/many.rb', line 123
def destroy(parent, relation, doc) doc.flagged_for_destroy = true if !doc. || parent.new_record? destroy_document(relation, doc) else parent.flagged_destroys.push(-> { destroy_document(relation, doc) }) end end
#destroy_document(relation, doc) (private)
Destroy the document.
# File 'lib/mongoid/association/nested/many.rb', line 141
def destroy_document(relation, doc) res = doc.destroy unless doc. || doc.destroyed? relation.delete(doc) res end
#destroyable?(attributes) ⇒ true
| false
(private)
Can the existing association potentially be deleted?
# File 'lib/mongoid/association/nested/many.rb', line 73
def destroyable?(attributes) destroy = attributes.delete(:_destroy) Nested::DESTROY_FLAGS.include?(destroy) && allow_destroy? end
#over_limit?(attributes) ⇒ true
| false
(private)
Are the supplied attributes of greater number than the supplied limit?
# File 'lib/mongoid/association/nested/many.rb', line 87
def over_limit?(attributes) limit = [:limit] limit ? attributes.size > limit : false end
#process_attributes(parent, attrs) (private)
Process each set of attributes one at a time for each potential new, existing, or ignored document.
# File 'lib/mongoid/association/nested/many.rb', line 102
def process_attributes(parent, attrs) return if reject?(parent, attrs) if (id = extract_id(attrs)) update_nested_relation(parent, id, attrs) else existing.push(Factory.build(@class_name, attrs)) unless destroyable?(attrs) end end
#update_document(doc, attrs) (private)
Update the document.
# File 'lib/mongoid/association/nested/many.rb', line 156
def update_document(doc, attrs) delete_id(attrs) if association. doc.assign_attributes(attrs) else doc.update_attributes(attrs) end end
#update_nested_relation(parent, id, attrs) (private)
Update nested association.
# File 'lib/mongoid/association/nested/many.rb', line 175
def update_nested_relation(parent, id, attrs) first = existing.first converted = first ? convert_id(first.class, id) : id if existing.where(_id: converted).exists? # document exists in association doc = existing.find(converted) if destroyable?(attrs) destroy(parent, existing, doc) else update_document(doc, attrs) end else # push existing document to association doc = association.klass.unscoped.find(converted) update_document(doc, attrs) existing.push(doc) unless destroyable?(attrs) end end