Object isn't being saved when called through association

I have three models in this small game I’m working on - the Game,
Players, and Turns. A Player should be able to rescue another Player
on any given turn. So it looks like this:

class Game
has_many :players
has_many :turns

def rescue_player§
t = turns.last
t.rescued = p
t.save
end
end

class Turn
belongs_to :rescued, :foreign_key => ‘rescued_id’, :class_name =>
‘Player’
end

class Player
belongs_to :game

def rescue_player§
game.rescue_player p
end
end

What I’m finding is that if I take a player and do
player.rescue_player p

Then it doesn’t actually save the results from the game#rescue_player
method. But if I call game.rescue_player§ directly, it does. I
have no clue what’s up, and it’s confusing the hell out of me. Am I
not allowed to access it like this or something?

Pat

One thing I’ve found is that the game object in Player#rescue_player
is not the same as the game object in Game#rescue_player. Here’s some
output from a test:

game is #Game:0x245c36c
player’s game is #Game:0x24471c4
game id is 1
player’s game id is 1

I think the objects ought to be the same, as the Player is related to
the Game…what’s going on?

One last thing, I just tried reloading the game object after calling
player.rescue_player, and it reflected the rescued player…but that
seems like a pretty ugly hack really. What am I doing wrong?

Pat

On 4/14/06, Justin F. [email protected] wrote:

I think the objects ought to be the same, as the Player is related to
regards

Justin


Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails

Yeah, that’s what I found…so is there any way I can use create the
DSL I want without resorting to lots of reload calls?

Pat

Pat M. wrote:

On 4/14/06, Justin F. [email protected] wrote:

Active Record doesn’t give you a unique in-memory representation of a
given database record. If you retrieve the same record more than once
you will get multiple instances representing it.

Yeah, that’s what I found…so is there any way I can use create the
DSL I want without resorting to lots of reload calls?

By DSL do you just mean “domain model”?

I suggest that you code your application based on an understanding of
the limitations of Active Record, and refactor out redundancy. You might
find that you end up with generic code ensuring unique representation of
each entity within a user’s session, or you might find that there are
only a few places where you need to guard against duplication.

regards

Justin

Pat M. wrote:

the Game…what’s going on?

One last thing, I just tried reloading the game object after calling
player.rescue_player, and it reflected the rescued player…but that
seems like a pretty ugly hack really. What am I doing wrong?

Active Record doesn’t give you a unique in-memory representation of a
given database record. If you retrieve the same record more than once
you will get multiple instances representing it.

regards

Justin

On 4/14/06, Justin F. [email protected] wrote:

By DSL do you just mean “domain model”?
I mean domain specific language.

One player should be able to rescue another player within the game.
Thus it would be really slick to be able to write
player.rescue another_player

That does modify the database as I need to, but it makes testing, as
well as some controller stuff, quite messy. For example, I want to
display the game details on the page, and rescue the player.

def rescue_player
@game = … # get’s the game based on some session info
player = … # again get’s player info based on session
another_player = Player.find params[:id]
player.rescue another_player
@game.reload
end

If I don’t do @game.reload, the @game object won’t accurately reflect
the db. First of all I just think it’s ugly to have to do that, and
secondly it’s pretty easy to forget the reload, not know when I need
to call it, etc.

Pat

Pat M. wrote:

I mean domain specific language.

One player should be able to rescue another player within the game.
Thus it would be really slick to be able to write
player.rescue another_player

OK. To me, that just looks like a feature of the domain model -
straightforward OO, with no metaprogramming required. (Contrast this
with the DSL for associations in Rails: has_many, belongs_to, etc.)

@game.reload
end

If I don’t do @game.reload, the @game object won’t accurately reflect
the db. First of all I just think it’s ugly to have to do that, and
secondly it’s pretty easy to forget the reload, not know when I need
to call it, etc.

From what you say, the game already contains information about the
players, so if you go to the database without involving the game, and
change anything, the game becomes out of date.

Perhaps you should do all finding of players (etc.) via the game, and
give it responsibility for holding these things uniquely.

regards

Justin