我的QuizzesController #index动作如下所示:
def index
@user = current_user
@quiz = Quiz.create(user_id: current_user.id)
end
我的观点很好地绘制了测验表格。它按预期转到结果/索引视图。但是,在QuizzesContoller #update操作中从数据库中提取的测验实例上没有更新测验的各种属性:
def update
@results = Quiz.where(user_id: current_user.id).last
redirect_to results_path
end
(在这种情况下调用'update',因为Quiz实例已经存在,已在'index'操作中创建)。
所以,我尝试将'更新'操作更改为:
def update
@quiz.save
@results = Quiz.where(user_id: current_user.id).last
redirect_to results_path
end
但这会触发错误:
undefined method 'save' for nil:NilClass
为什么?我的QuizzesController不应该访问'index'动作中设置的@quiz变量吗?任何人都可以解释那里有什么问题吗?
答案 0 :(得分:1)
其他人回答了这个问题,所以我想我会解释为什么答案就是这样。在Ruby中,以@符号开头的变量是实例变量。这意味着它们是在实例化其父对象的新实例时创建的,并且对于该对象的实例是唯一的。
基于Rails的Web应用程序,大多数情况下都是无状态的,这意味着http请求之间不会持久存在状态。通俗地说,app会独立于所有其他请求处理每个请求。因此,控制器是实例类。每个请求都实例化一个控制器类的新实例。
编辑:
更多我看你的代码,你没有遵循正确的约定
class QuizzesController < ApplicationController
# GET index: for displaying a list of quizzes
def index
@quizzes = Quiz.where(user_id: current_user.id)
end
# GET show: for getting a single quiz record
def show
@quiz = Quiz.find(params[:id])
end
# GET new: for initializing a new quiz record
def new
@quiz = Quiz.new
end
# POST create: for saving a new quiz record
def create
@quiz = current_user.quizzes.create(quiz_params)
if @quiz.errors
render :new
else
redirect_to @quiz #or whereever
end
end
# GET edit: for initializing existing quiz for update
def edit
@quiz = Quiz.find(params[:id)
end
# PUT/PATCH update: for updating an existing quiz record
def update
@quiz = Quiz.find(params[:id])
if @quiz.update(quiz_params)
redirect_to @quiz # or whereever
else
render :edit
end
# DELETE destroy: for deleting a quiz record
def destroy
Quiz.find(params[:id]).destroy
redirect_to :index # or whereever
end
end
答案 1 :(得分:0)
您的更新操作中没有@quiz
变量。控制器中的操作无法访问其他操作中的变量。
答案 2 :(得分:0)
QuizzesController
实例不会在请求之间保留。在控制器中使用的真正原因实例变量是将该变量传递给视图。
正常的更新操作如下所示:
def update
@quiz = current_user.quiz # I'm assuming a user has one quiz?
@quiz.update(quiz_params) # Where quiz params takes the posted parameters from your update form
if @quiz.errors.any?
render :edit
else
redirect_to results_path
end
关键是您需要为每个请求重新分配@quiz