Module: Mongoid::Association::Referenced::AutoSave
- Extended by:
- ActiveSupport::Concern
- Included in:
- Mongoid::Association
- Defined in:
- lib/mongoid/association/referenced/auto_save.rb
Overview
Mixin module included into Mongoid::Document which adds the ability to automatically save opposite-side documents in referenced associations when saving the subject document.
Class Method Summary collapse
-
.define_autosave!(association) ⇒ Class
Define the autosave method on an association’s owning class for an associated object.
Instance Method Summary collapse
-
#__autosaving__ ⇒ Object
Begin the associated autosave.
-
#autosaved? ⇒ true | false
Used to prevent infinite loops in associated autosaves.
-
#changed_for_autosave?(doc, seen = Set.new) ⇒ true | false
Check if there are changes for auto-saving.
Class Method Details
.define_autosave!(association) ⇒ Class
Define the autosave method on an association’s owning class for an associated object.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/mongoid/association/referenced/auto_save.rb', line 64 def self.define_autosave!(association) association.inverse_class.tap do |klass| save_method = :"autosave_documents_for_#{association.name}" klass.send(:define_method, save_method) do if before_callback_halted? self.before_callback_halted = false else __autosaving__ do if assoc_value = ivar(association.name) Array(assoc_value).each do |doc| next unless changed_for_autosave?(doc) pc = doc.persistence_context? ? doc.persistence_context : persistence_context.for_child(doc) doc.with(pc) do |d| d.save end end end end end end klass.after_persist_parent save_method, unless: :autosaved? end end |
Instance Method Details
#__autosaving__ ⇒ Object
Begin the associated autosave.
28 29 30 31 32 33 |
# File 'lib/mongoid/association/referenced/auto_save.rb', line 28 def __autosaving__ Threaded.begin_autosave(self) yield ensure Threaded.exit_autosave(self) end |
#autosaved? ⇒ true | false
Used to prevent infinite loops in associated autosaves.
20 21 22 |
# File 'lib/mongoid/association/referenced/auto_save.rb', line 20 def autosaved? Threaded.autosaved?(self) end |
#changed_for_autosave?(doc, seen = Set.new) ⇒ true | false
Check if there are changes for auto-saving. Returns true if the document is new, changed, or marked for destruction, or if any in-memory referenced child with autosave: true recursively satisfies the same condition.
The seen set prevents infinite recursion when autosave associations form a cycle (e.g. a belongs_to with autosave: true whose target has a has_many with autosave: true pointing back).
48 49 50 51 52 53 |
# File 'lib/mongoid/association/referenced/auto_save.rb', line 48 def changed_for_autosave?(doc, seen = Set.new) return false unless seen.add?(doc) doc.new_record? || doc.changed? || doc.marked_for_destruction? || autosave_children_changed?(doc, seen) end |