背景:我基本上有一个多项选择测验。当用户提交表单时,update
会对其答案进行评分,选择新问题,将消息放入闪存中,然后重定向回show
操作。 show
显示消息和新问题。
当前的问题是,如果他们两次提交表单,update
会被调用两次。第一次为他们给出的问题得分答案。第二次为刚刚选出的问题得分,他们还没有看到。因此,他们会被重定向,并发出一条消息,说“"错误!答案是西班牙,而不是意大利"当他们选择氢气和氦气时。
所以我的第一个解决方案是在提交的表单中包含一个question_id字段。如果提交的ID不是所询问问题的ID,请忽略此请求。这适用于跟踪,但存储在闪存中的消息将丢失。
如果ids不匹配,我已尝试添加flash.keep
。我的想法是,一个update
将设置闪存,然后接收的下一个请求将是第二个update
。但闪光灯仍在迷失。似乎第二个update
根本不是以闪光开始的,这让我很困惑。
所以我的问题是:有没有更好的方法来处理这个问题?如果没有,为什么闪光灯会消失?
update
看起来像这样(省略了一些行):
def update
game = current_user.credence_game
question = game.current_question
if params[:question_id].to_i == question.id
given_answer = params[:answer_index].to_i
credence = params[:credence].to_i
correct, score = question.score_answer(given_answer, credence)
game.score += score
game.new_question
game.save
flash[:correct] = correct
flash[:score] = score
flash[:message] = question.answer_message(given_answer)
else
flash.keep
end
redirect_to action: 'show'
end
如果我在p flash
之前添加redirect_to
行,服务器就会吐出:
#<ActionDispatch::Flash::FlashHash:0x007f2a8431b4a0 @used=#<Set: {}>, @closed=false, @flashes={:correct=>false, :score=>-32, :message=>"Incorrect. The right answer is White River (Arkansas) (1102km) versus Yellowstone River (1080km)."}, @now=nil>
Started PUT "/credence" for 127.0.0.1 at 2014-08-17 15:20:16 +0100
Processing by CredenceController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"EiqXDoFy77nmdKOE4YkHOeEFg4DvB5zdgFi98ynNCx0=", "question_id"=>"52", "credence"=>"60", "answer_index"=>"1", "commit"=>"60%"}
<Model stuff>
Redirected to http://localhost:3000/credence
Completed 302 Found in 667ms
#<ActionDispatch::Flash::FlashHash:0x000000059864f8 @used=#<Set: {}>, @closed=false, @flashes={}, @now=nil>
Started PUT "/credence" for 127.0.0.1 at 2014-08-17 15:20:18 +0100
Processing by CredenceController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"EiqXDoFy77nmdKOE4YkHOeEFg4DvB5zdgFi98ynNCx0=", "question_id"=>"52", "credence"=>"70", "answer_index"=>"1", "commit"=>"70%"}
<Model stuff, just loading the game and the question>
Redirected to http://localhost:3000/credence
Completed 302 Found in 421ms
Started GET "/credence" for 127.0.0.1 at 2014-08-17 15:20:19 +0100
Processing by CredenceController#show as HTML
<Model stuff>
Rendered layouts/_messages.html.erb (400.4ms)
Completed 200 OK in 963ms (Views: 776.4ms | ActiveRecord: 27.7ms)
<GET requests for CSS, images, etc.>
所以它看起来像闪光灯设置后的第一个请求,是我打电话给flash.keep
的那个,但它仍然没有闪光灯。
编辑:我意识到问题很可能是我使用CookieStore。第一个请求在发送第二个请求之前没有机会设置cookie。使用会话代替flash会产生同样的问题。
这里的一个简单的解决方案,我不太喜欢,只是简单地使用javascript onsubmit禁用表单。一个更复杂的问题是:当问题ID不匹配时,查找用户为提交的问题ID提供的答案,并在不改变分数的情况下适当设置闪光灯。
任何替代方案?