2010-11-10 26 views
9

Tôi đã sau đây thiết lậpRails:: inverse_of và Hiệp hội phần mở rộng

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 

Điều này có nghĩa các công việc sau:

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 

Nhưng sau không cư xử theo cùng một cách:

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 

Làm cách nào để tạo mối quan hệ :inverse_of với các phương pháp mở rộng? (Đây có phải chỉ là lỗi không?)

Trả lời

7

Tôi đã tìm thấy một workaround if (như tôi), bạn có sẵn sàng từ bỏ việc tối ưu hóa SQL do Arel và chỉ làm tất cả trong 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 

Bằng cách viết phần mở rộng để lọc trong Ruby kết quả đầy đủ các hiệp hội, chứ không phải thu hẹp các truy vấn SQL, kết quả trả về bởi việc gia hạn cư xử đúng với :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 
Các vấn đề liên quan