2010-11-10 11 views
9

Tengo el siguiente set-upRieles: extensiones: inverse_of y asociación

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 

Esto significa que las siguientes obras:

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 

pero los siguientes no se comporta de la misma manera:

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 

¿Cómo puedo hacer que la relación :inverse_of se extienda a los métodos de extensión? (¿Es esto solo un error?)

Respuesta

7

Me han encontrado una solución si (como yo) que está dispuesto a renunciar a la optimización de SQL otorgado por Arel y simplemente hacerlo todo 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 

Al escribir la extensión de filtrar en Ruby los resultados completos de la asociación, en lugar de la reducción a la consulta SQL, los resultados devueltos por la extensión se comportan correctamente con :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 
Cuestiones relacionadas