I was working on a custom association for my gem GitHub - crashtech/torque-postgresql: Add support to complex resources of PostgreSQL, like data types, array associations, and auxiliary statements (CTE) and I found a misleading concept, so I want to confirm if it could/should be fixed.
The problem is related to AutosaveAssociation
class, more precisely #add_autosave_association_callbacks. The condition states that any collection
based association will be saved after the owner record is saved.
However, the order is more related to where the foreing_key
is saved than the number of records. Every time that the foreing_key
is stored in the owner
, it should always save the association before saving the record, regardless if it is a collection or not.
I was able to go around this condition by overriding the add_autosave_association_callbacks
method. But, if the condition was aligned to the concept, then I could have only overridden save_belongs_to_association
. Then, here is my proposed fix:
def add_autosave_association_callbacks(reflection)
save_method = :"autosave_associated_records_for_#{reflection.name}"
if reflection.belongs_to?
define_non_cyclic_method(save_method) { throw(:abort) if save_belongs_to_association(reflection) == false }
before_save save_method
elsif reflection.has_one?
define_method(save_method) { save_has_one_association(reflection) } unless method_defined?(save_method)
# 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
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
end
define_autosave_validation_callbacks(reflection)
end