为什么我不能在'update'动作中引用我的@quiz变量?

时间:2014-12-15 16:13:44

标签: ruby-on-rails

我的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变量吗?任何人都可以解释那里有什么问题吗?

3 个答案:

答案 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