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 lib/active_record/autosave_association.rb, line 182 182: def add_autosave_association_callbacks(reflection) 183: save_method = :"autosave_associated_records_for_#{reflection.name}" 184: validation_method = :"validate_associated_records_for_#{reflection.name}" 185: collection = reflection.collection? 186: 187: unless method_defined?(save_method) 188: if collection 189: before_save :before_save_collection_association 190: 191: define_non_cyclic_method(save_method, reflection) { save_collection_association(reflection) } 192: # Doesn't use after_save as that would save associations added in after_create/after_update twice 193: after_create save_method 194: after_update save_method 195: else 196: if reflection.macro == :has_one 197: define_method(save_method) { save_has_one_association(reflection) } 198: # Configures two callbacks instead of a single after_save so that 199: # the model may rely on their execution order relative to its 200: # own callbacks. 201: # 202: # For example, given that after_creates run before after_saves, if 203: # we configured instead an after_save there would be no way to fire 204: # a custom after_create callback after the child association gets 205: # created. 206: after_create save_method 207: after_update save_method 208: else 209: define_non_cyclic_method(save_method, reflection) { save_belongs_to_association(reflection) } 210: before_save save_method 211: end 212: end 213: end 214: 215: if reflection.validate? && !method_defined?(validation_method) 216: method = (collection ? :validate_collection_association : :validate_single_association) 217: define_non_cyclic_method(validation_method, reflection) { send(method, reflection) } 218: validate validation_method 219: end 220: end
# File lib/active_record/autosave_association.rb, line 154 154: def define_non_cyclic_method(name, reflection, &block) 155: define_method(name) do |*args| 156: result = true; @_already_called ||= {} 157: # Loop prevention for validation of associations 158: unless @_already_called[[name, reflection.name]] 159: begin 160: @_already_called[[name, reflection.name]]=true 161: result = instance_eval(&block) 162: ensure 163: @_already_called[[name, reflection.name]]=false 164: end 165: end 166: 167: result 168: end 169: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.