Rails 中新控制器操作的目的是什么?
脚手架生成如下新操作:
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
操作也实例化了一个新对象。它只是用来将表单绑定到一个对象,以便一切都正确地从一个动作到另一个动作吗?
A scaffold generates the new action like this:
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
and the view renders a partial, named form
. Since the new
form renders with the action set to create a new product, what is the purpose of @product
? I see that the create
action instantiates a new object as well. Is it only used so that you can tie the form to an object, so that everything goes from action to action correctly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以将新操作中的 @product 视为未保存的对象,它只是填写视图中呈现的表单字段。这使得 new.html.erb 与 edit.html.erb 几乎相同,并允许它们共享单个部分 _form.html.erb。
当在新操作中使用此部分时,字段将由新的、空的且未保存的 @product 对象填充。这是新操作中出现的 Product.new。当在编辑操作中使用部分时,您将获得一个 @product 对象,该对象可能具有其所有属性的值。现在,假设您没有在新操作中使用@product。 new.html.erb 中使用的表单需要与 edit 中使用的表单不同。如果您向模型添加新字段,祝您维护它们好运。
此方法的另一个优点是,您可以在新 @product 的属性在视图中呈现之前预先填充它们。假设您要使用名称“新产品”作为每个产品的默认名称。您可以通过以下方式在新操作中执行此操作:
You can think of @product in the new action as being an unsaved object that simply fills out the form fields that are rendered in the view. This makes new.html.erb pretty much the same as edit.html.erb and allows them to share a single partial, _form.html.erb.
When this partial is used in the new action, the fields are populated by a fresh, empty, and unsaved @product object. This is the Product.new that appears in the new action. When the partial is used in the edit action, you've got a @product object that presumably has values for all its attributes. Now, suppose you didn't use @product in the new action. The form used in new.html.erb would need to be different than the form used in edit. Good luck maintaining them if you ever add a new field to the model.
Another advantage of this approach is that you can pre-populate attributes of the new @product before they're rendered in the view. Suppose you want to use the name "new product" as the default name for each product. You can do this in the new action this way:
一个主要目的是让您可以使用相同的表单进行新建和编辑。
控制器传递 @product 对象(新的或现有的),Rails 会查看它是新记录还是现有记录。它根据此做出某些决定,例如将记录值拉入输入字段(现有)以及在提交时发送表单的控制器操作。
One main purpose is so that you can use the same form for new and edit.
The controller passes the @product object (new or existing) and Rails sees whether it's a new record or an existing record. It makes certain decisions based on that such as to pull the record values into the input fields (existing) and which controller action to send the form on submission.
如果您有 form_for,则新操作用于正确初始化
form_for @product
中的 @product,它需要 ActiveRecord 模型。如果我没记错的话,产品的范围(对于任何控制器操作)以请求结束,因此创建操作不知道新操作,需要初始化另一个产品。form_for
方法使用@product
变量将表单正确分配给资源控制器,以查找正确的 URL、id(在更新的情况下)等。您可以在 http://guides.rubyonrails.org/form_helpers.html如果您担心内存使用情况,则不必初始化
@product
,但是您必须手动创建自己的表单,而不使用基于资源的form_for
。If you have a form_for, the new action is used to properly initialize the @product in
form_for @product
, which expects an ActiveRecord model. If I remember correctly, the Product's scope (for any controller action) ends with the request, so the create action has no knowledge of the new action, requiring another Product to be initialized.The
form_for
method uses the@product
variable to correctly assign the form to the resource controller to find the correct URL, id (in the case of an update), and more. You can read about it in section 2.3 of http://guides.rubyonrails.org/form_helpers.htmlIf you're that concerned about memory usage, you don't have to initialize
@product
, but then you would have to manually create your own form without using the nice resource-basedform_for
.