编辑表单从使用脚手架时获取它的实例变量在哪里?

时间:2015-10-07 16:16:20

标签: ruby-on-rails ruby-on-rails-4

在使用rails的脚手架中,新操作需要创建一个新的记录实例:

def new
  @greeting = Greeting.new
end

这是为新视图建立初始表单的方式,该视图使用form_for @greeting 同样,通过我们的创建操作:

def create
  @greeting = Greeting.new(greeting_params)

  respond_to do |format|
    if @greeting.save
      format.html { redirect_to @greeting, notice: 'Greeting was successfully created.' }
      format.json { render :show, status: :created, location: @greeting }
    else
      format.html { render :new }
      format.json { render json: @greeting.errors, status: :unprocessable_entity }
    end
  end
end

传递来自强params的表单数据,创建一个新实例并保存它。然而,当谈到编辑动作时,我们什么都没有:

def edit
end

视图只是在_form.html.erb文件中呈现表单。除此之外,对我而言,一切都是有道理的:

在_form.html.erb文件中,你有这个:

form_for(@greeting) do |f|

这是@greeting,我没有得到。获取此@greeting变量的表单在哪里,如果它不在编辑操作中?我原本以为它可能是以某种方式在动作之间共享但我无法在动作之间共享实例变量(我实际上尝试在另一个动作中创建一个实例变量,然后在视图中渲染它并且它不起作用)。然后我想我的应用程序控制器中可能有一些东西,但这就是我的应用程序控制器的样子:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
end

基本上,编辑似乎没有任何逻辑位置来获取此@greeting变量数据。我还注意到编辑表单预先填充了数据库中已有的数据。谁能解释一下这里发生了什么?为什么这个@greeting表单不会出错?为什么预先填充了用户数据?

2 个答案:

答案 0 :(得分:0)

实例变量在before_action过滤器中初始化,在控制器操作之前调用该过滤器。

我已经剥夺了所有不相关的内容:

class GreetingsController < ApplicationController
  before_action :set_greeting, only: [:show, :edit, :update, :destroy]

  def edit
  end

  private
  def set_greeting
    @greeting = Greeting.find(params[:id])
  end
end

尽管它似乎是Rails的方式,但我建议不要采用这种做法,因为可能不清楚事情的来源。

相反,我通常做这样的事情:

class GreetingsController < ApplicationController
  before_action :set_greeting, only: [:show, :edit, :update, :destroy]

  def edit
    @greeting = find_greeting
  end

  private
  def find_greeting
    Greeting.find(params[:id])
  end
end

它有点冗长,但也更清晰。

您可以在Rails documentation中了解控制器过滤器的工作原理。

答案 1 :(得分:0)

  

获取此@greeting变量的表单在哪里,如果它不在   编辑动作?

如果您查看控制器,将会有一个类似这样的before_action过滤器

before_action :set_greeting, only: [:show, :edit, :update, :destroy]

private
# Use callbacks to share common setup or constraints between actions.
def set_greeting
  @greeting = Greeting.find(params[:id])
end

因此,set_greeting负责设置编辑表单中使用的@greeting