如何使这项工作成为一个has_many:通过

时间:2013-03-15 04:40:28

标签: ruby-on-rails

我想知道你是否可以给我一些关于如何使用has_many的建议:通过关联在这种情况下我花了很多时间重写我的代码可能无济于事。

我有一个用户模型,每个用户都可以玩很多测验(因此可以生成很多测验分数)。现在,玩家通过点击用户名来启动游戏,这会触发对该用户(用户has_many:问题)所做的所有测验问题的查询

  def startGame 

     user = User.find_by_name(params[:user])
     questions = user.questions

  end 

由于显而易见的原因,玩家不能两次玩相同的测验。虽然我想出了一种方法来防止这种情况,但我没有采用有效的方法。有人建议我尝试一个关联表。我使用此计划将该关联表作为has_many :through启动

User.rb(此用户是用户为播放器,而非用户即测验制作者)

has_many :scores
has_many :quizzes, :through => :scores

Quiz.rb

   has_many :scores
   has_many :users    :through => :scores

得分

   belongs_to :user
   belongs_to :quiz

问题是,目前没有测验模型或测验任何东西。测验实际上只是由问题(Question.rb)和答案(Answer.rb)组成。例如,每个用户has_many :questions和每个问题has_many :answers都是这样的

User.rb

has_many :questions

Question.rb

has_many :answers

那么我可以制作测验模型(或者我称之为的任何模型)?

我想到的一个想法是创建一个Quiz.rb模型并执行

has_many :questions

这意味着Question.rb同时属于User.rb和Quiz.rb.

然后,如上所述,我可以使用用户,测验和分数执行has_many :through吗?如果是这样,分数将同时具有user_id(对于玩家)和quiz_id(对于测验),但由于整个关联的目的是阻止用户两次播放相同的测验,我想知道我是如何做到的使用以下代码。

  def startGame

   user = User.find_by_name(params[:user])  #this user is the quiz creator
   questions = user.questions
     .....
    #I want to check right here if they've already played the quiz. how to do it with the has_many :through of Quiz, Score, User (as player)

  end

设置了user.rb(播放器),score.rb,quiz.rb,如何在这种情况下检查他们是否玩过这个特定的测验。

另外,如果我制作测验模型并执行has_many:问题,我是否必须使用多态,因为user.rb也有has_many:问题?

更新:我想检查他们是否已经使用def startGame方法进行游戏,如果有的话,不要让他们继续比赛。即我不想等到保存得分才能看到该测验的得分是否已经保存。

1 个答案:

答案 0 :(得分:2)

您的代码看起来非常好。如果您想阻止任何玩家多次玩测验,您可以将用户和测验的任意组合设为唯一。您可以将此添加到您的分数迁移中:

add_index :scores, [:user_id, :quiz_id], unique: true

并将其添加到您的Scores模型中:

validates_uniqueness_of :user_id, scope: quiz_id