【问题标题】:Rails: :inverse_of and Association extensionsRails: :inverse_of 和关联扩展
【发布时间】:2010-11-10 15:49:36
【问题描述】:

我有以下设置

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 关系扩展到扩展方法? (这只是一个错误吗?)

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 associations inverse


    【解决方案1】:

    如果(像我一样)您愿意放弃 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
    

    【讨论】:

      【解决方案2】:

      它不起作用,因为“in_hand”方法有一个返回数据库的查询。

      由于 inverse_of 选项,工作代码知道如何使用已经在内存中的对象。

      http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

      【讨论】:

      • 好的,有没有办法让它与“in_hand”方法一起工作?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多