Custom Association Method - Can This Be Done

2020-03-04 07:32发布

I have three models: Wager, Race, RaceCard and WagerType. I've created a has_many association in Wagers and have added a custom association method (in_wager). The purposes of the method is to filter the correct races for each wager. (Some wagers span multiple races). I'd like to be able to do somethings like: Wager.first.races.in_wager and have the appropriate races returned.

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

My custom method works fine if I hardcode the values for a and b, however, I need those values to be dynamic. Specifically, the value of b should equal the race_nbr attribute from the Wager model:

b = wagers.race_nbr

and the value of a should equal b minus the Number Of Race for the particular Wager type (know as Legs) plus 1:

a = b - Legs + 1  

The value for legs is in the WagerType model. Note Wagers belong_to WagerType and WagerType has_many Wagers. Therefore, a could be expressed as:

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

MY Question: Is it actually possible to do this with my in_wager association method. I've been banging my head on this for a couple of evening now and can't quite figure out how to assign the correct values to a and b. Also if you feel I'm coming at this the wrong way, I'd be happy to hear alternative approaches. Thanks for your help.

Note: I never really mentioned the RaceCard or Races models. They have the following associations:

class RaceCard < ActiveRecord::Base
  has_many :races
end

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

Update: I was reading Design Patterns in Ruby last night and came across the Proc. I'm going to see if I can use it within the Association method to calculate the values for a and b.

2条回答
SAY GOODBYE
2楼-- · 2020-03-04 08:03

Do you absolutely need to use an has_many relation ? maybe you could just create a method in the Wager class

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 

I don't really understand your model, so the request is certainly wrong, but you get the idea...

查看更多
该账号已被封号
3楼-- · 2020-03-04 08:15

you can use self.proxy_association.owner to get the parent object inside of an association method. From there you can get the values you want.

If I understand your models correctly then the code should look something like this.

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

The I got this from the Rails api reference to Association Extensions (The reference to proxy_association is at the bottom of the section).

查看更多
登录 后发表回答