【问题标题】:What is the purpose of the new controller action in Rails?Rails 中新的控制器动作的目的是什么?
【发布时间】:2011-03-10 01:20:43
【问题描述】:

一个脚手架像这样生成新的动作:

  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 操作也实例化了一个新对象。是否仅用于将表单绑定到对象,以便一切从一个动作到另一个动作正确进行?

【问题讨论】:

    标签: ruby-on-rails ruby scaffolding controllers


    【解决方案1】:

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

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

    这种方法的另一个优点是您可以在新@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
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

        • 是的,但我不明白这有什么好处。当create 动作被调用时,它会重新定义@product
        • 我刚刚编辑了答案,所以我想你可能没有看到它。 @product 的范围在操作(或请求)内。它的状态不会保留给下一个请求,即创建操作。
        • 是的,@product 在动作完成时消失是有道理的,但为什么要使用它呢?为什么不使用与模型无关的表单?对我来说,这似乎只是浪费内存。我确信这一定有一个潜在的目的,但我还没有看到它。
        • Rails 使用了一点“魔法”,因为没有更好的术语,来找到正确的资源控制器、操作、id(在更新的情况下),用@product 构建 form_for .
        • 我已经更新了答案,提供了一个 Rails 指南的链接。
        猜你喜欢
        • 2016-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-06
        相关资源
        最近更新 更多