Rails中新控制器操作的目的是什么?

时间:2011-03-09 16:47:20

标签: ruby-on-rails ruby scaffolding controllers

脚手架会生成如下所示的新动作:

  def new
    @product = Product.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @product }
    end
  end

 def create
    @product = Product.new(params[:product])

    respond_to do |format|
      if @product.save
        format.html { redirect_to(@product, :notice => 'Product was successfully created.') }
        format.xml  { render :xml => @product, :status => :created, :location => @product }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @product.errors, :status => :unprocessable_entity }
      end
    end
  end

并且视图呈现部分名为form的部分。由于new表单使用操作集进行渲染以创建新产品,@product的目的是什么?我看到create动作也实例化了一个新对象。是否仅使用它以便您可以将表单绑定到对象,以便所有操作都能正确地从操作到操作?

3 个答案:

答案 0 :(得分:4)

您可以将新操作中的@product视为未保存的对象,只是填充在视图中呈现的表单字段。这使得new.html.erb与edit.html.erb几乎相同,并允许它们共享单个部分_form.html.erb。

在新操作中使用此部分时,字段将由新的,空的和未保存的@product对象填充。这是出现在新操作中的Product.new。当在编辑操作中使用partial时,您有一个@product对象,该对象可能具有其所有属性的值。现在,假设您没有在新操作中使用@product。 new.html.erb中使用的表单需要与编辑中使用的表单不​​同。如果您在模型中添加新字段,请运气好。

此方法的另一个优点是,您可以在视图中呈现之前预先填充新@product的属性。假设您要使用名称“new product”作为每个产品的默认名称。您可以通过这种方式在新操作中执行此操作:

def new
    @product = Product.new(:name => 'new product')

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @product }
    end
  end

答案 1 :(得分:3)

一个主要目的是让您可以使用相同的表单进行新建和编辑。

控制器传递@product对象(新的或现有的),Rails查看它是新记录还是现有记录。它根据这些做出某些决定,例如将记录值拉入输入字段(现有)以及在提交时发送表单的控制器操作。

答案 2 :(得分:1)

如果您有form_for,则新操作用于正确初始化form_for @product中的@product,该产品需要ActiveRecord模型。如果我没记错的话,产品的范围(对于任何控制器操作)都以请求结束,因此创建操作不了解新操作,需要初始化另一个产品。

form_for方法使用@product变量将表单正确分配给资源控制器,以查找正确的URL,id(在更新的情况下)等。您可以在http://guides.rubyonrails.org/form_helpers.html

的第2.3节中阅读相关内容

如果您担心内存使用情况,则不必初始化@product,但是您必须手动创建自己的表单而不使用基于资源的form_for