Module: ActiveRecord::AutosaveAssociation::ClassMethods
Do not use. This module is for internal use only.
Relationships & Source Files | |
Defined in: | activerecord/lib/active_record/autosave_association.rb |
Instance Method Summary
-
#add_autosave_association_callbacks(reflection)
private
Adds validation and save callbacks for the association as specified by the
reflection
. - #define_autosave_validation_callbacks(reflection) private
- #define_non_cyclic_method(name, &block) private
Instance Method Details
#add_autosave_association_callbacks(reflection) (private)
Adds validation and save callbacks for the association as specified by the reflection
.
For performance reasons, we don’t check whether to validate at runtime. However the validation and callback methods are lazy and those methods get created when they are invoked for the very first time. However, this can change, for instance, when using nested attributes, which is called after the association has been defined. Since we don’t want the callbacks to get defined multiple times, there are guards that check if the save or validation methods have already been defined before actually defining them.
# File 'activerecord/lib/active_record/autosave_association.rb', line 189
def add_autosave_association_callbacks(reflection) save_method = :"autosave_associated_records_for_#{reflection.name}" if reflection.collection? around_save :around_save_collection_association define_non_cyclic_method(save_method) { save_collection_association(reflection) } # Doesn't use after_save as that would save associations added in after_create/after_update twice after_create save_method after_update save_method elsif reflection.has_one? define_non_cyclic_method(save_method) { save_has_one_association(reflection) } # Configures two callbacks instead of a single after_save so that # the model may rely on their execution order relative to its # own callbacks. # # For example, given that after_creates run before after_saves, if # we configured instead an after_save there would be no way to fire # a custom after_create callback after the child association gets # created. after_create save_method after_update save_method else define_non_cyclic_method(save_method) { throw(:abort) if save_belongs_to_association(reflection) == false } before_save save_method end define_autosave_validation_callbacks(reflection) end
#define_autosave_validation_callbacks(reflection) (private)
[ GitHub ]# File 'activerecord/lib/active_record/autosave_association.rb', line 219
def define_autosave_validation_callbacks(reflection) validation_method = :"validate_associated_records_for_#{reflection.name}" if reflection.validate? && !method_defined?(validation_method) if reflection.collection? method = :validate_collection_association elsif reflection.has_one? method = :validate_has_one_association else method = :validate_belongs_to_association end define_non_cyclic_method(validation_method) { send(method, reflection) } validate validation_method after_validation :_ensure_no_duplicate_errors end end
#define_non_cyclic_method(name, &block) (private)
[ GitHub ]# File 'activerecord/lib/active_record/autosave_association.rb', line 159
def define_non_cyclic_method(name, &block) return if method_defined?(name, false) define_method(name) do |*args| result = true; @_already_called ||= {} # Loop prevention for validation of associations unless @_already_called[name] begin @_already_called[name] = true result = instance_eval(&block) ensure @_already_called[name] = false end end result end end