2013-03-15 4 views
0

Мне интересно, можете ли вы дать мне несколько советов о том, как использовать has_many: через объединение в этой ситуации, прежде чем я потрачу много времени на переписывание моего кода, возможно, нет помогло.Как сделать эту работу как 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 

Score

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: questions, мне пришлось бы использовать полиморфизм, так как user.rb также has_many: вопросы?

Обновление: Я хочу проверить, были ли они уже сыграны в методе def startGame и не позволяют им продолжать игру, если они есть. т. е. я не хочу ждать, пока пришло время сохранить счет, чтобы проверить, был ли счет для этой викторины уже сохранен.

ответ

2

Ваш код выглядит очень хорошо.Если вы хотите, чтобы любой игрок не играл викторину более одного раза, вы можете сделать любую комбинацию пользователя и викторину уникальной. Вы можете добавить к вашей миграции баллов:

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

И добавить к вашей модели Множества:

validates_uniqueness_of :user_id, scope: quiz_id 
+0

Спасибо за совет, но это значит, что вы могли бы сделать все то же самое. Итак, вы будете делать Quiz.rb has_many: вопросы? Имеет ли значение, что User.rb уже has_many: вопросы? мне нужно использовать полиморфизм? Хорошо ли «как есть», что у Викторины и Пользователя есть has_many: вопросы? – BrainLikeADullPencil

+1

Ваш ответ, кажется, предполагает, что я выполняю проверку уникальности после того, как они снова сыграют (и, предположительно, не позволяют им сохранять, если они уже играли один раз). Тем не менее, я хочу проверить метод startGame и остановить их повторное воспроизведение. – BrainLikeADullPencil

+0

@BrainLikeADullPencil: вы можете проверить «викторины», чтобы увидеть, есть ли там викторина и жаловаться, если вы ее найдете. –