I would love to understand recursiveness and what I've done to create a circular reference.
class SomeModel
# callback to calculate something only if the status_id has been changed
after_save :calculate_something if: :status_id_changed?
def calculate_something
# this unless combined with the callback if means this is only run if not only the status_id has been changed, but that it's been changed to a non-nil value
unless self.status_id.nil?
self.run_first_calculation
end
end
def run_first_calculation
self.save(validate:false)
end
end
I'm getting a stack level too deep
error because of the self.save(validate:false)
. But I'm not sure why because saving with a validation false does not change the status_id
, but when I have a regular self.save
, it's fine.
If you take the above, and run in the console:
some_model_instance.update_attribute(:status_id, 2)
# => stack level too deep
I don't get why. Here's what I think is happening:
some_model_instance
gets an updatedstatus_id
- because of that, the callback runs (now we're in
run_calculations
) - because the
status_id
is not nil, we are inside theunless
block - the
run_first_calculation
method is called - we save
some_model_instance
arbitrarily - but because the
status_id
is not changed, we shouldn't run into the callback again