【问题标题】:Custom Association Method - Can This Be Done自定义关联方法 - 可以这样做吗
【发布时间】:2012-01-25 02:44:31
【问题描述】:

我有三个模型:Wager、Race、RaceCard 和 WagerType。我在 Wagers 中创建了一个 has_many 关联,并添加了一个自定义关联方法 (in_wager)。该方法的目的是为每个投注过滤正确的比赛。 (一些赌注跨越多场比赛)。我希望能够执行以下操作:Wager.first.races.in_wager 并返回适当的比赛。

class Wager < ActiveRecord::Base
  belongs_to :wager_type
  belongs_to :race_card
  has_many :races, :through => :race_card do
     def in_wager 
       where('races.race_nbr BETWEEN ? AND ?', a, b)
     end
  end
end

如果我硬编码 a 和 b 的值,我的自定义方法可以正常工作,但是,我需要这些值是动态的。具体来说,b 的值应该等于 Wager 模型中的 race_nbr 属性:

b = wagers.race_nbr

a 的值应该等于 b 减去特定投注类型(称为 Legs)的 Number Of Race 加 1:

a = b - Legs + 1  

legs 的值在 WagerType 模型中。注意投注belong_to WagerType 和WagerType has_many Wagers。因此,a可以表示为:

a = (b - (select wager_types.legs where wagers_types.id = wagers.wager_type_id) + 1)

我的问题:实际上是否可以使用我的 in_wager 关联方法来做到这一点。几个晚上,我一直在努力解决这个问题,但不知道如何为 a 和 b 分配正确的值。另外,如果您觉得我的做法是错误的,我很乐意听到其他方法。感谢您的帮助。

注意:我从未真正提及 RaceCard 或 Races 模型。它们具有以下关联:

class RaceCard < ActiveRecord::Base
  has_many :races
end

class Races < ActiveRecord::Base
  belongs_to :race_card
  has_many :wagers, :through => :race_card
end

更新:我昨晚在阅读《Ruby 中的设计模式》时遇到了 Proc。我将看看是否可以在 Association 方法中使用它来计算 a 和 b 的值。

【问题讨论】:

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


    【解决方案1】:

    您可以使用self.proxy_association.owner 在关联方法中获取父对象。从那里你可以得到你想要的值。

    如果我正确理解了您的模型,那么代码应该如下所示。

    class Wager < ActiveRecord::Base
    belongs_to :wager_type
    belongs_to :race_card
      has_many :races, :through => :race_card do
        def in_wager
          owner = self.proxy_association.owner
          b = owner.race_nbr
          a = b - owner.wager_type.legs + 1
          where('races.race_nbr BETWEEN ? AND ?', a, b)
        end
      end
    end
    

    我从 Rails api 引用中得到这个,引用 Association Extensions(对 proxy_association 的引用在该部分的底部)。

    【讨论】:

    • Azolo - 谢谢!那成功了。就在他晚上,我尝试在协会中使用 self。我只是不知道proxy_association.owner。今晚我肯定会读到更多关于它的信息。再次感谢。
    【解决方案2】:

    你绝对需要使用has_many 关系吗?也许你可以在 Wager 类中创建一个方法

    def races
      b = self.race_nbr
      a = b + self.race_card.legs
      Races.find_by_race_card_id(self.id).where('race_nbr BETWEEN ? AND ?', a, b)
    end 
    

    我不太了解你的模型,所以请求肯定是错误的,但你明白了......

    【讨论】:

    • 感谢您的意见。这可行,但不符合我的应用程序要求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-09
    • 1970-01-01
    • 2012-02-19
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    相关资源
    最近更新 更多