Rails: :inverse_of和关联扩展

9
我有以下的设置:
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

这意味着以下内容可以正常运作:
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

但是下面的内容却表现不同:
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

我该如何使:inverse_of关系扩展到扩展方法中?(这只是一个bug吗?)
2个回答

7

如果你愿意放弃Arel提供的SQL优化,只使用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

通过使用Ruby编写扩展程序来过滤关联的全部结果,而不是缩小SQL查询范围,扩展程序返回的结果能够正确地与: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

4

1
好的,有没有办法让它与“in_hand”方法一起工作? - Chowlett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接