【问题标题】:Rails: Create dynamic amount of relationships upon creating a new modelRails:在创建新模型时创建动态数量的关系
【发布时间】:2015-06-26 20:23:25
【问题描述】:

在我们的应用中,用户可以通过会员资格加入投注。每个投注可以有多个回合,并且每个回合都有许多玩家(用户),这取决于在创建回合时谁是投注的成员。

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

我是 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

【问题讨论】:

  • 我希望将回合的合同与投注的会员资格完全分开,因为有人可以通过创建会员资格加入投注,玩几回合,然后通过销毁他们的会员资格退出投注。如果一个投注会员破坏了他们的会员资格,我仍然希望他们通过他们参与的所有轮次的合同来记录投注历史

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


【解决方案1】:

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

用户 -> 合约 -> 回合 -> 下注

采用这种方式,您可以在 Round 模型中将 :memberships 作为别名处理。

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

Contract 模型的格式看起来包含 user_idround_id,每次用户参与 Round 时,您将创建一个 Contract 模型以将该参与表示为“成员”。换句话说,创建合约不是额外的步骤,而是让用户进入一轮的基本动作。具体来说,您可以编写以下内容:

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 以获取用户参与的所有投注。

【讨论】:

  • 您好,感谢您的回复。就我现在的代码而言,我的模型关系将是
  • 您好,感谢您的回复。就我现在的代码而言,我的模型关系将是 Bet 通过会员资格拥有许多用户,并且一个赌注也有很多轮(直接,没有使用关系模型)。一轮通过合约有很多用户。我希望用户能够加入和离开赌注(创建和销毁会员资格),但始终记录他们在成为赌注成员时参与的回合(即使会员资格被删除,也希望维持所有合同) .我对 Rails 很陌生,您的建议是否允许这种功能?
  • 换句话说,每一轮都是由一个赌注@round = @bet.rounds.build(..)组成的,并且这一轮的所有合约都由该赌注当前拥有的成员(用户)(通过会员资格)确定。在创建回合时,我如何(通过关系)为下注的每个成员(用户)签订合同?
  • 请记住,投注的成员会来来去去,但每一轮的合同不应受到某人离开投注的影响
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-05
  • 1970-01-01
  • 2011-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多