我正在尝试设置一个类似游戏的Rails应用程序。该应用程序具有用户,每个用户都可以创建Pawns。用户可以使用他们自己的一个Pawns搜索其他用户和他们创建的Pawns,并在他们喜欢的情况下挑战另一个用户。受挑战的用户可以接受/拒绝挑战。
现在我可以为用户添加/删除Pawns,我的模型看起来像这样:
class User < ActiveRecord::Base
has_many :pawns, dependent: :destroy
和
class Pawn < ActiveRecord::Base
belongs_to :user
现在,如果User1想要挑战User2创建的Pawn,他会查看User2的Pawn列表并点击他想要的Pawn的“Challenge”按钮。然后,User1必须选择他的一个Pawns用于挑战并点击保存。现在User2需要接受/拒绝挑战。
我很难理解应该如何设置挑战。我的想法是,每个Pawn都会有一个自我引用的多对多关系,几乎就像建立友谊关系一样。但是,我不知道是否应该考虑与用户或Pawn相关的挑战。
最好的方法是建模这样的东西吗?
修改
这是我想要完成的图表。我definitley认为我需要某种关联设置。结果将保存该挑战的Pawn统计数据(类似于time_spent,clicks_made等)。挑战也会有一个赢家或类似的专栏。
答案 0 :(得分: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
您的用户可以通过棋子与棋子和挑战相关联。获得与用户相关联的两种挑战类型的简单方法是将两个挑战关联(发起和接收)的结果合并到一个方法#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
此方法的性能优化可能包括将challenge_上的user_ids非规范化为challengee_user_id和:challenger_user_id ...或者在用户上缓存挑战ID列表,这样您就可以进行一次查询而不是两次查询。
答案 1 :(得分:2)
您可以设置另一个名为Challenges
的表格,其中包含字段challenger_id, challengee_id, status
。挑战者和挑战者ID当然代表了当然,而不是用户。状态代表challenge_pending, challenge_on_going
,显然还有其他方法可以做到这一点,但是这一个。
这样做的另一个好处是,如果这是你想要的行为,你可以很容易地将pawn-pawn挑战限制为一个。
在视图控制器中
@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 %>
答案 2 :(得分: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