Rails:在创建新模型时创建动态数量的关系

时间:2015-06-26 20:23:26

标签: ruby-on-rails ruby-on-rails-4 relational-database

在我们的应用中,用户可以通过会员加入投注。每个投注可以有多轮,并且每一轮都有许多玩家(用户),这些玩家(用户)基于谁是创建该轮次时的投注成员。

一轮通过合同有很多玩家(Round和User之间的关系)。基本上,我希望能够创建一个新的回合并为每个下注成员的用户自动创建合约。会员可以加入和离开投注,任何只有在他们有赌注会员资格时创建的轮次中的一部分。

我是Rails的新手,并且无法想出为每个拥有赌注成员资格的用户自动建立合同关系的方法。任何想法真的很感激!!

class Bet < ActiveRecord::Base  
  has_many :memberships, dependent: :destroy
#
  has_many :agree_members,   -> { where(memberships: { accepted: true }).where(memberships: { against: false }) }, through: :memberships, source: :user
  has_many :against_members, -> { where(memberships: { accepted: true }).where(memberships: { against: true }) },  through: :memberships, source: :user
#
  has_many :agree_requesters,   -> { where(memberships: { accepted: false }).where(memberships: { against: false }) }, through: :memberships, source: :user
  has_many :against_requesters, -> { where(memberships: { accepted: false }).where(memberships: { against: true }) },  through: :memberships, source: :user

  def members
    agree_members | against_members
  end
#
  def requests
    agree_requesters | against_requesters
  end

  has_many :rounds
end

============

class Round < ActiveRecord::Base
  belongs_to :bet 

  has_many :contracts, dependent: :destroy

  has_many :potential_winners, -> { where(contracts: { agrees: true, agree_wins: true, signed: false }) }, through: :contracts, source: :user
  has_many :potential_losers, -> { where(contracts: { agrees: true, agree_wins: false, signed: false }) }, through: :contracts, source: :user

  has_many :winners, -> { where(contracts: { agrees: true, agree_wins: true, signed: true }) }, through: :contracts, source: :user
  has_many :losers, -> { where(contracts: { agrees: true, agree_wins: false, signed: true }) }, through: :contracts, source: :user

end

==============

class User < ActiveRecord::Base
# BETS (and bet memberships)
  has_many :memberships

  has_many :agree_bets,   -> { where(memberships: { accepted: true }).where(memberships: { against: false }) },  through: :memberships, source: :bet
  has_many :against_bets, -> { where(memberships: { accepted: true }).where(memberships: { against: true }) },   through: :memberships, source: :bet

  has_many :pending_bets, -> { where(memberships: { accepted: false }) }, through: :memberships, source: :bet

  def active_bets
    agree_bets | against_bets
  end

  def joined_bets
    active_bets | pending_bets
  end

# ROUNDS (and contracts)
has_many :contracts

#IGNORE THIS LOGIC, NOT SET UP YET AND NOT RELEVANT
has_many :agree_maybe_wins,     -> { where(contracts: { agree: true }).where(memberships: { against: false }) },  through: :contracts, source: :round
has_many :against_maybe_wins,   -> { where(contracts: { agree: true }).where(memberships: { against: false }) },  through: :contracts, source: :round

has_many :agree_maybe_loses,    -> { where(contracts: { agree: true }).where(memberships: { against: false }) },  through: :contracts, source: :round
has_many :against_maybe_loses,  -> { where(contracts: { agree: true }).where(memberships: { against: false }) },  through: :contracts, source: :round


has_many :agree_wins,   -> { where(contracts: { agree: true }).where(memberships: { against: false }) },  through: :contracts, source: :round
has_many :against_wins, -> { where(contracts: { agree: true }).where(memberships: { against: false }) },  through: :contracts, source: :round


has_many :agree_losses,   -> { where(contracts: { agree: true }).where(memberships: { against: false }) },  through: :contracts, source: :round
has_many :against_losses, -> { where(contracts: { agree: true }).where(memberships: { against: false }) },  through: :contracts, source: :round



def potential_wins
  agree_maybe_wins | against_maybe_wins
end

def wins
  agree_wins | against_wins
end

def potential_losses
  agree_maybe_wins | against_maybe_wins
end

def losses
  agree_wins | against_wins
end



end

1 个答案:

答案 0 :(得分:1)

这里的一种方法是has_many :through关系。如果我正确理解您的应用程序,您的模型关系可以概括为:

用户 - &gt;合同 - &gt;圆形 - &gt;下注

以这种方式构思,您可以处理:成员资格作为Round模型中的别名。

Class Round
  has_many :memberships, class_name: "User", through: :contracts
end

如果格式的Contract模型包含user_idround_id,则每次用户参与Round时,您都会创建Contract模型表示作为&#34;成员&#34;的参与。换句话说,创建合同不是一个额外的步骤,而是进入一轮的用户的基本行动。具体来说,您可以编写以下内容:

class User
  def self.add_to_round(round_id)
    Contract.create(user_id: self.id, round_id: round_id)
  end
end

然后查询Round.first.membersUser.first.rounds等内容。

为方便起见,您可能还希望创建另一个has_many :through关系,允许您直接从用户查询到投注(或相反)。这看起来像是:

class User
  has_many :rounds, through: :contracts
  has_many :bets, through: :rounds
end

在这两种关系到位的情况下,您应该可以调用User.first.bets来获取用户参与的所有赌注。