Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

ActiveRecord caching has_many :through

#5687

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

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

State: invalid
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Jon Leighton
    Jon Leighton
    • 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)

    December 21st, 2010 @ 06:48 PM

  2. Barak
    Barak

    Hi Jon, thanks for the reply.

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

    December 21st, 2010 @ 11:56 PM