3

我有一个非常简单的表格,在我尝试重新提交之前可以正常工作。之后,它会更新记录而不是创建新记录:

在我看来,我有这个:

#new_order_form
  = render 'form'

我的表格部分:

= semantic_form_for [@location, @order], :remote => true do |f|
  -if @order.errors.any?
    #notice{:class=>'alert alert-block alert-error fade in'}
      %a{:class=>"close", :data=>{:dismiss=>"alert", :href=>"#"}}
        x
      %h3  
        = pluralize(@order.errors.count, "error")
      - @order.errors.full_messages.each do |msg|
        = msg
        %br

  %table{:class => 'table table-bordered', :style=> {width: '50%'}}  
    %tr
      %td= f.text_field :product_order_id, :placeholder => "Order ID"

在我的 create.js 中:

$("#new_order_form").html("<%= escape_javascript(render("form")) %>");

这可以很好地创建订单并呈现错误(如果存在)。

问题是:如果我在不刷新页面的情况下输入另一个订单号,它会更新之前创建的记录,而不是创建一个新记录。

查看表单代码,我可以看到提交操作已替换为更新。

我试图用这个替换代码:

 = semantic_form_for [@location, @order], :remote => true do |f|
   #new_order_form
     = render 'form', :f => f

这在 create.js

$("#new_order_form").html("<%= escape_javascript(render :partial => 'form', :locals => {:f => @order}) %>");

这也不起作用并抱怨无效的文本字段。

做这个的最好方式是什么?谢谢

4

3 回答 3

1

我不熟悉semantic_form_for,但我认为它是常规的超集form_for

工作方式form_for是它检查模型以查看它是否被持久化,然后执行默认操作以匹配它。我个人认为form_foredit动作中调用会假设update,但事实并非如此。form_for将假定该操作create适用于任何非持久模型和update任何持久模型。如果你愿意,我相信你可以覆盖它,但我自己没有尝试过。

听起来您可能正在做的是显示模型并尝试在同一页面上创建新模型。(如果我错了,请包含您的控制器,因为很难说出您打算做什么。)您的控制器中可能需要 a@show_order和 a @new_order

我希望这会有所帮助,如果没有,也许您可​​以提供有关控制器的更多详细信息。

编辑:

每当您希望能够创建新模型时,您需要确保您的控制器调用@new_order = Order.new并确保form_for使用@new_order. new_只是区分新旧的前缀。

在这种情况下,我不确定控制器是否是order#show或者可能是order#create.

因为show你想要这样的东西:

@order = Order.find(params[:id])
@new_order = Order.new

如果你这样做,create你可能想要:

@order = Order.new(params[:order])

if @order.save
  @new_order = Order.new
  redirect_to ???
else
  render :new
end

以上所有内容都应与库存控制器完全匹配,除了添加@new_order. (换句话说,如果存在respond_toandformat行,请不要删除它们。)

于 2013-01-16T19:48:33.517 回答
1

问题是您的 create.js 正在读取来自创建操作结果的@order,这是现有的@order,因此它成为更新。

一个解决方法:在你的“if @order.save”创建部分创建一个新的@order:@order_new = Order.new。

现在告诉您的表单部分使用 order 而不是 @order :

semantic_form_for [@location, order], :remote => true do |f|

使用以下内容更新您的 create.js:

$("#new_order_form").html("<%= escape_javascript(render 'form', :order => @order_new) %>");

确保将任何引用表单渲染的内容更新为也使用 :order => @order。例如:

<%= render 'form', :order => @order %>

如果您的 @location 需要是一个新实例,那么同样的规则也适用。

我使用@order_new 而不是覆盖@order,以防您想在create.js 中使用@order 做某事

旁注(对于其他查看者): Rails 3.x 渲染方法不需要 partials => 和 locals => 帮助器。

于 2013-01-20T00:53:58.573 回答
1

我不是这个主题的专家,但亚当的回答似乎是正确的。我假设您的控制器操作中有如下内容:

def create
  @order = Order.new(params[:order])

  if @order.save
    responds_to do |format|
      format.js
      format.html { redirect_to 'xxx' }
    end
  else
    responds_to do |format|
      format.js
      format.html { render :new }
    end
  end
end

如果你有上述结构,那么 create.js.erb 只是传递了 @order.save 调用之后已经修改的 @order 对象。您可以在通过的条件中重新定义它,如下所示(检查第 4 行):

def create
  @order = Order.new(params[:order])

  if @order.save
    @order = Order.new
    responds_to do |format|
      format.js
      format.html { redirect_to 'xxx' }
    end
  else
    responds_to do |format|
      format.js
      format.html { render :new }
    end
  end
end

现在如果@order 已成功保存,将创建并传递新订单。否则将传递带有验证错误的旧@order。希望这会有所帮助。

于 2013-01-26T05:22:43.637 回答