Player != Player?

–sorry if this double posted … tried using online google groups interface to submit … that was an hour ago.–

I’m developing an hobby application designed to provide some utilities
for a favorite boardgame of mine. I can’t say exactly what problem I’m

having, but I can describe two symptoms that I’ve discovered have the
same root:

1.) When loading a page for the second time since the server started,
@player.technologies turns up method_missing (Player.has_many


2.) When loading a page for the second time since the server started,
@game.players << raises an AssocationTypeMismatch
complaining that “Player expected, got Player”. Huh?

While investigating the first I discovered that on the second page
load since the server started, @player.reflect_on_all_associat

== 0. But on the first page load, there were 6! So somehow it “lost” my

associations. I did a sanity check. Yep, on the second page load
Player.reflections.size == 6 but @player.class.reflections == 0 … yet
@player.class.to_s == ‘Player’. Wow. So confused.

Well further digging revealed that on the second page load

@player.class != Player even though @player.class.to_s == Player.to_s.
Huh? That’s the same problem as issue #2.

Ok, so now at least I know the problems have the same root cause. I did
a lot more tracing through ActiveRecord. Stayed up a few hours. Whipped

myself with a wet noodle. Ended up putting some debugging messages into
ActiveRecord::Reflection::AssocationReflection.klass. Whenever that
method gets called, if self == Game I do some sanity checks to see if

@klass == Player.

class AssociationReflection < MacroReflection #:nodoc:
  def klass
    if active_record.to_s == 'Game'
      puts 'Player == compute type: ' + (Player ==

active_record.send(:compute_type, class_name)).to_s
puts 'Player == @klass: ’ + (Player == @klass).to_s if @klass
@klass ||= active_record.send(:compute_type, class_name)


On the first page load, both sanity checks return true. On the second
page load, the first returns true and the second returns false. That
is, on the first page load @klass == Player, but on the second page

load @klass != Player (even though @klass.to_s == ‘Player’ all the way

What’s up? Anyone? Do I need a bigger noodle?

Your model classes get re-created on each request in development mode.
That's how you get the nice "just refresh the browser" behavior. e.g.
try "puts Player.object_id". You'll see it's a different object each
time round.

I looks like somehow your app is keeping hold of an instance from a
previous request, which is therefore an instance of the "old" player
class. Are you storing a player in the session? If so try storing the
id of the player instead and reloading it from the db on each request.


Ok, this could be a problem: my Game model is also my Session model.
That is:

  CGI::Session::ActiveRecordStore.session_class = Game

I started looking into object_ids a half hour after posting, and you're
right. Player.object_id != @klass.object_id on the second page load,
because @klass is not getting cleared from the first page. I just tried
setting @klass to nil before any controller logic, and it solved my

Magic code:
before_filter {Game.reflections[:players].send(:instance_variable_set,
'@klass', nil)} if RAILS_ENV == 'development'

I'm sure there's a better way to solve this. Like maybe I shouldn't be
using my Session model as my Game model. But I can't help but think
that I'll want to have associations from Session models in other apps,
so I wish I could learn something more useful here.