I have a problem with making changes to an object from within another model as well as within the object's model. I have the following models:
class Foo < ActiveRecord::Base
has_many :bars
def do_something
self.value -= 1
# Complicated code doing other things to this Foo
bars[0].do_other
save!
end
end
class Bar < ActiveRecord::Base
belongs_to :foo
def do_other
foo.value += 2
foo.save!
end
end
If I have a Foo object with value set to 1, and call do_something on it, I can see from my database logs the following two operations:
Foo Update (0.0s) UPDATE "foos" SET "value" = 2 WHERE "id" = 1
Foo Update (0.0s) UPDATE "foos" SET "value" = 0 WHERE "id" = 1
... so do_something is presumably caching the self object. Can I avoid this, other than by moving the save!s around?
ActiveRecord provides a reload method for reloading the attributes of a model object from the database. The source code for this method is:
# File vendor/rails/activerecord/lib/active_record/base.rb, line 2687
def reload(options = nil)
clear_aggregation_cache
clear_association_cache
@attributes.update(self.class.find(self.id, options).instance_variable_get('@attributes'))
@attributes_cache = {}
self
end
—As you can see it calls a clear_association_cache method, so there's definitely caching of associations going on which would explain the behaviour you're seeing. You should probably reload the model in one of your methods prior to saving.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With