我目前正在为我的游戏应用程序开发一个评分系统,出于某种原因,积分并没有加起来。目标是每当玩家猜到正确的答案时,点数就会增加。对于每个新玩家,分数设置为0.
问题#validate_answer :
def validate_answer
@correct_answer = Answer.where(correct: true).map(&:text)
@selected_answer = params[:answer]
@player_score = Player.where(id: params[:id]).map(&:score)
if @correct_answer.include? (@selected_answer)
@player_score[0] += 1
render :success
else
render :error
end
end
Quesiton.rb
class Question < ActiveRecord::Base
belongs_to :category
has_many :answers
has_one :video_clue
has_many :answers
def correct_answer
answers.find_by correct: true
end
end
Answer.rb
class Answer < ActiveRecord::Base
belongs_to :question
end
Player.rb
class Player < ActiveRecord::Base
has_secure_password
def admin?
self.admin == 'admin'
end
end
答案和播放器的架构表
create_table "answers", force: :cascade do |t|
t.integer "question_id"
t.string "text"
t.boolean "correct"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "answers", ["question_id"], name: "index_answers_on_question_id", using: :btree
create_table "players", force: :cascade do |t|
t.string "user_name"
t.string "password_digest"
t.integer "score"
t.string "role"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
答案 0 :(得分:1)
我会像这样重构代码:
def validate_answer
@question = Question.find(params[:q_id])
@correct_answer = Answer.find_by_question_id(params[:q_id]).text.downcase
@selected_answer = params[:answer].downcase
@player = Player.find(params[:id])
if @selected_answer == @correct_answer
@player.increment!(:score)
render :success
else
render :error
end
end
increment!
自动为指定的列ping @player
对象。它省去了尝试将其转换为数组并访问索引的麻烦。
注意:每个聊天对话编辑回答。
答案 1 :(得分:0)
只看到需要为该
做更少的代码行def validate_answer
#i think this is a bad approach to compare the text of the answer
#with the text of the given answer
#the better one would be to assing UUID to the answer or just use the regular ID
# something like this params[:answer][:uuid]
# or params[:answer][:id]
# we need to find the answer related to the question, otherwise we
# could throw in just random IDs and they are still saying "correct"
given_answer = Questions.find(params[:question_id]).answers.find params[:answer][:id]
# if we use UUID we dont need to give the question id, since then the ID can't be guessed
if given_answer.correct?
# current_user is a player.
# current_user is a method from devise (u should use devise)
current_user.award_points! given_answer
render :success
else
ender :error
end
end
class Player
def award_points! answer
# adding the points to the user
# and save it
current_user.award_points += answer.points
current_user.save
#better approach would be to save the question which was answered for the user
# like has_many :answered_questions
# so then u could also track which questions already been answered by the user and not awarding him twice
end
end