如何在 simple_form_for 实例中维护信息直到通过正确答案

How to maintain information in a simple_form_for instance until a correct answer is passed

我正在尝试创建一个简单的 rails 网站,我可以用它来练习心算。这个想法是我使用我定义的随机选择的 ruby question_creator 函数创建一个随机问题。这个函数 returns 两个数字,连同他们的答案。

如果用户键入的答案不正确,我想显示一条快速错误消息并再次显示相同的问题。在重新显示问题时,我想跟踪找到正确答案所需的尝试次数,以及这样做的总时间。

我现在卡住的地方是我无法弄清楚如何维护随机生成的问题,以及在输入错误后重新加载 simple_form_for 时尝试的次数。

为了做到这一点,我创建了一个名为 Questions 的模型,其中包含每个问题的尝试次数和时间。理想情况下,我想在正确回答问题时创建该对象的实例。为每个已回答的问题设置一个问题实例的想法是,我以后可以使用它来跟踪我的进度和改进。

现在问题架构如下所示:

 create_table "questions", force: :cascade do |t|
    t.integer "trys"
    t.integer "time"
    t.bigint "user_id"
    t.bigint "question_type_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["user_id"], name: "index_questions_on_user_id"
  end

My Questions class 生成随机问题的方法如下所示。我不确定这是否是此方法的正确位置,因此也请随时对此提供反馈。我的想法是,最后我有几个不同的问题,例如add_two_numbers()multiply_two_numbers()subtract_three_numbers()等...我每次都可以从中随机选择一个。

 def random_two_digit_number()
    return rand(10..99)
  end

  def add_two_numbers()
    num1 = random_two_digit_number()
    num2 = random_two_digit_number()
    answ = num1 + num2
    return num1, num2, answ
  end

为了传递用户答案,连同实际答案 answ 到创建方法,我将它们作为隐藏字段添加到我的 simple_form_for.My Question/New 页面中,如下所示:

<% @question = Question.new() %>

<% num1, num2, answ = @question.add_two_numbers %>
<h3>  <%= num1 %> + <%= num2 %></h3>

<p>Trys: <%= @question.trys %></p>

<%= simple_form_for @question do |f| %>
  <%= f.hidden_field :trys, :value => @question.trys || 1 %>
  <%= f.hidden_field :answ, :value => answ %>
  <%= f.input :user_answ, input_html: {value: ''}  %>
  <%= f.button :submit %>
<% end %>

问题控制器中的创建方法:

def create
    @question = Question.new(trys: question_params["trys"], time: question_params["time"])
    @question.user_id = current_user.id
    respond_to do |format|
      if @question.save && (question_params["answ"] == question_params["user_answ"])
        format.html { render :new, notice: 'Correct!' }
        format.json { render :show, status: :created, location: @question }
      else
        format.html { render :new, notice: 'Thats wrong' }
        format.json { render json: @question.errors, status: :unprocessable_entity }
      end
    end
  end

每当我遇到 question_params["answ"] == question_params["user_answ"] 的时候,这意味着用户给出了错误的答案,我想将尝试计数增加 1 并将他重定向到同一个问题。截至目前,我无法让它工作。

我已经在 python 中构建了一个快速原型,如果有帮助的话:https://codeshare.io/arlrX7

如果有人能为我指明正确的方向,我会非常高兴,因为我真的很想让它发挥作用:)

此代码有很多问题,但让我们解决那些阻止您使其正常工作的问题。

  1. 在你的 new.html.erb 中你有两行有问题 -
<% @question = Question.new() %>
<% num1, num2, answ = @question.add_two_numbers %>

在你的观点中有逻辑是一个坏主意,它也会阻止你实现你的目标。在控制器的 new 操作中定义它们。

  1. 下一站 - 提交表单。您现在在新操作中分配@question 和@num1 及其朋友,并且您的表单仍然有效。但是,唉,这还没有解决问题。如果在你的 create 动作中有那些相同的变量,你现在需要什么, 因为 当你 render :new, notice: 'Thats wrong' 时,它是在创建的上下文中使用局部变量完成的在这种情况下可用。

因此,将 num1 和 fiends 作为隐藏字段添加到您的表单中,并在 create 操作中分配这些值。

@num1 = question_params[:num1]

这样,当您 render :new 时,您仍然拥有那些 @question@num1 以及您传递的任何其他内容

  1. 最后,您控制器中的这一行:
 if @question.save && (question_params["answ"] == question_params["user_answ"])

它的作用是保存问题然后检查答案。相反,尝试:

 @question.save if (question_params["answ"] == question_params["user_answ"])

if @question.persisted? # rest of your code

这样您只在答案正确时才保存问题,然后检查它是否已保存以确定下一步要做什么。