2

Suppose I have the following model relationship:

class Player < ActiveRecord::Base
  has_many :cards
end

class Card < ActiveRecord::Base
  belongs_to :player
end

I know from this question that Rails will return me a copy of the object representing a database row, meaning that:

p = Player.find(:first)
c = p.cards[0]
c.player.object_id == p.object_id # => false

...and therefore if the Player model modifies self, and the Card model modifies self.player in the same request, then the modifications won't take any notice of each other and the last-saved one will overwrite the others.

I'd like to work around this (presumably with some form of caching), so that all requests for a Player with a given id would return the same object (identical object_ids), thereby allowing both models to edit the same object without having to perform a database save-and-reload. I have three questions:

  1. Is there already a plugin or gem to do this?
  2. Are there good reasons why I shouldn't do this?
  3. Can anyone give me some pointers on how to go about doing this?
Community
  • 1
  • 1
Chowlett
  • 45,935
  • 20
  • 116
  • 150
  • Can you better explain the use case of editing the player from both the player object and the card object? – rwilliams Nov 06 '10 at 09:56
  • See the linked question. Suppose it costs a player 1 action to play a Card, and there is a certain type of card which grants 2 actions when you play it. Then I want to do `self.actions -= 1` in Player, and `player.actions += 1` in the Card subclass. – Chowlett Nov 09 '10 at 09:27

1 Answers1

3

This is supported in Rails 3.x. You can use the :inverse_of option for the has_many association for example. Documentation here (search for :inverse_of and Bi-directional associations).

Zabba
  • 64,285
  • 47
  • 179
  • 207
  • Ok, yes, that looks like it works. All I'll need to do is go through and replace some constructs (I have separate `has_many` relationships for hand_cards and deck_cards) with proper association extensions. Which I should probably do anyway. Bounty is yours once I've given that a go. – Chowlett Nov 09 '10 at 09:58