2

我正在尝试设置一个类似于游戏的 Rails 应用程序。该应用程序有用户,每个用户都有他们可以创建的 Pawn。用户可以搜索其他用户和他们创建的 Pawn,如果愿意,可以使用自己的 Pawn 挑战另一个用户。然后,被挑战的用户可以接受/拒绝挑战。

现在我可以为用户添加/删除 Pawns,我的模型如下所示:

class User < ActiveRecord::Base
  has_many :pawns, dependent: :destroy

class Pawn < ActiveRecord::Base
  belongs_to :user

现在,如果 User1 想要挑战由 User2 创建的 Pawn,他查看 User2 的 Pawn 列表并单击他想要的 Pawn 的“挑战”按钮。然后,用户 1 必须选择他的一个 Pawns 用于挑战并单击保存。现在 User2 需要接受/拒绝挑战。

我很难弄清楚应该如何设置挑战。我的想法是每个 Pawn 都会有一个自我参照的多对多关系,就像建立友谊关系一样。但是,我不知道我是否应该考虑与用户或 Pawn 相关的挑战。

模拟这样的东西的最佳方法是什么?

编辑:

这是我要完成的工作的图表。我definitley认为我需要某种关联设置。结果将保存该挑战的该 Pawn 的统计信息(例如 time_spent、clicks_made 等)。挑战也会有一个获胜者或类似内容的列。

在此处输入图像描述

4

3 回答 3

3

您的挑战可能为每种类型的棋子定义了关联。

class Challenge < ActiveRecord::Base
  # attributes :challengee_id, :challenger_id

  belongs_to :challengee, class_name: "Pawn"
  belongs_to :challenger, class_name: "Pawn"

  has_many :results
end

Pawns 对每种类型的挑战都有关联。

class Pawn < ActiveRecord::Base
  # attributes :user_id

  belongs_to :user

  has_many :results
  has_many :initiated_challenges, class_name: "Challenge", foreign_key: :challenger_id
  has_many :received_challenges, class_name: "Challenge", foreign_key: :challengee_id
end

对结果记录的challenge_id 进行非规范化可能是可以的。

class Result < ActiveRecord::Base
  # attributes: pawn_id, challenge_id, :result
  belongs_to :pawn
  belongs_to :challenge
end

您的用户可以通过 pawn 与 pawn 和挑战建立关联。将两种挑战类型与用户关联的一种简单方法是将两种挑战关联(发起和接收)的结果组合到一个方法#challenge。

class User < ActiveRecord::Base
  has_many :pawns
  has_many :initiated_challenges, through: :pawns, source: :initiated_challenges
  has_many :received_challenges, through: :pawns, source: :received_challenges

  def challenges
    initiated_challenges + received_challenges
  end
end

此方法的性能优化可能包括将挑战中的 user_id 非规范化为 :challengee_user_id 和 :challenger_user_id... 或缓存用户上的挑战 id 列表,以便您进行一次查询而不是两次。

于 2012-09-23T16:52:15.180 回答
2

您可以设置另一个名为Challenges字段的表challenger_id, challengee_id, status。挑战者和挑战者 ID 当然代表棋子,而不是用户。状态将代表challenge_pending, challenge_on_going,显然还有其他方法可以做到这一点,但这是一种。

这还有一个额外的好处,即如果这是您想要的行为,您可以非常轻松地将典当挑战限制为一个。

在您的视图控制器中

@challenges = Challenge.where("challengee_id IN (?)", Pawn.find_all_by_owner_id(current_user.id).map{|u| u[:id]})
@challenged = Challenge.where("challenger_id IN (?)", Pawn.find_all_by_owner_id(current_user.id).map{|u| u[:id]})

在你看来

<%= @challenges.each do |challenge| %>
  whatever
<% end %>
于 2012-09-16T00:04:17.490 回答
1
class User < ActiveRecord::Base
    has_many :pawns
end

class Pawn < ActiveRecord::Base
    belongs_to :user

    has_many :challengers, class_name: 'Challenge'
    has_many :challengees, class_name: 'Challenge'

    belongs_to :result
end

class Challenge < ActiveRecord::Base
    belongs_to :challenger, class_name: 'Pawn'
    belongs_to :challengee, class_name: 'Pawn'

    belongs_to :result
end

class Result < ActiveRecord::Base
    has_one :challenge
    has_one :winner, class_name: 'Pawn'
end
于 2012-09-19T22:22:35.333 回答