2010-11-10 3 views
9

Je donne les résultats suivants set-upRails:: extensions de inverse_of et d'association

class Player < ActiveRecord::Base 
    has_many :cards, :inverse_of => :player do 
    def in_hand 
     find_all_by_location('hand') 
    end 
    end 
end 

class Card < ActiveRecord::Base 
    belongs_to :player, :inverse_of => :cards 
end 

Cela signifie que les travaux suivants:

p = Player.find(:first) 
c = p.cards[0] 
p.score # => 2 
c.player.score # => 2 
p.score += 1 
c.player.score # => 3 
c.player.score += 2 
p.score # => 5 

Mais ce qui suit ne se comporte pas de la même façon:

p = Player.find(:first) 
c = p.cards.in_hand[0] 
p.score # => 2 
c.player.score # => 2 
p.score += 1 
c.player.score # => 2 
c.player.score += 2 
p.score # => 3 

d = p.cards.in_hand[1] 
d.player.score # => 2 

Comment puis-je étendre la relation :inverse_of aux méthodes d'extension? (Est-ce juste un bogue?)

Répondre

7

J'ai trouvé une solution de contournement si (comme je suis), vous êtes prêt à renoncer à l'optimisation SQL accordée par Arel et juste tout faire en Ruby.

class Player < ActiveRecord::Base 
    has_many :cards, :inverse_of => :player do 
    def in_hand 
     select {|c| c.location == 'hand'} 
    end 
    end 
end 

class Card < ActiveRecord::Base 
    belongs_to :player, :inverse_of => :cards 
end 

En écrivant l'extension pour filtrer en Ruby les résultats complets de l'association, plutôt que de circonscrire la requête SQL, les résultats renvoyés par l'extension se comportent correctement avec :inverse_of:

p = Player.find(:first) 
c = p.cards[0] 
p.score # => 2 
c.player.score # => 2 
p.score += 1 
c.player.score # => 3 
c.player.score += 2 
p.score # => 5 

d = p.cards.in_hand[0] 
d.player.score # => 5 
d.player.score += 3 
c.player.score # => 8