This project is archived and is in readonly mode.

#5687 ✓invalid
Barak

ActiveRecord caching has_many :through

Reported by Barak | September 22nd, 2010 @ 10:56 PM

The second assert of this test incorrectly fails. However, when the first assert is removed, the second assert will pass. Looks like ActiveRecord is caching the value of me.favorite_pets, and Favorite.new isn't invalidating the cache.

test "favorite pet" do
  me = User.new({:name => 'Me'})
  sparky = Pet.new({:name => 'Sparky'})
  assert_equal [], me.favorite_pets
  Favorite.new({:user => me, :favorite_thing => sparky}).save
  assert_equal [sparky], me.favorite_pets
end

The models are as follows:

class User < ActiveRecord::Base
  has_many :favorites
  has_many :favorite_pets, :through => :favorites, :source => :pet
  has_many :favorite_movies, :through => :favorites, :source => :movie
end
class Favorite < ActiveRecord::Base
  belongs_to :user
  belongs_to :favorite_thing, :polymorphic => true
  belongs_to :pet, :foreign_key => :favorite_thing_id
  belongs_to :movie, :foreign_key => :favorite_thing_id
end

Comments and changes to this ticket

  • Jon Leighton

    Jon Leighton December 21st, 2010 @ 06:48 PM

    • State changed from “new” to “invalid”
    • Importance changed from “” to “Low”

    Thanks for the bug report.

    In the example you've given, the first time you run me.favorite_pets, it goes to the database and get the answer (empty). It then remembers the answer until there is a reason to forget it.

    When you do Favorite.new, your me object doesn't know anything about it. So when you run me.favorite_pets again it just returns the same result because it doesn't realise that the result has changed.

    To fix your code, you could:

    • Run me.favorite_pets(true) to force the association to be reloaded
    • Create the Favorite object by doing me.favorites.new(:favorite_thing => sparky)
  • Barak

    Barak December 21st, 2010 @ 11:56 PM

    Hi Jon, thanks for the reply.

    I wasn't aware that me.favorite_pets(true) existed. Very useful thing to know. Thanks again.

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Pages