Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cache problems when updating an object from another model

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?

like image 250
Chowlett Avatar asked Dec 30 '25 00:12

Chowlett


1 Answers

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.

like image 139
John Topley Avatar answered Jan 01 '26 14:01

John Topley