在使用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表单不会出错?为什么预先填充了用户数据?
答案 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
。