Rails 3 -指定远程表单提交后的表单操作



我有一个非常简单的表单,工作良好,直到我尝试重新提交。在此之后,它更新记录而不是创建新记录:

在我看来,我有这个:

#new_order_form
  = render 'form'

和我的form partial:

= 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}) %>");

也不工作,并报错无效的text_field。

最好的方法是什么?由于

我不是这方面的专家,但是Adam的回答似乎是正确的。我假设你的控制器动作中有如下内容:

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之后修改的@order对象。保存调用。您可以在传递的条件中重新定义它,如下所示(检查第2行)。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。

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

一个修复:创建一个新的@order: @order_new = Order。新在您的'if @订单。保存"create section"。

现在告诉你的form partial使用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渲染方法不需要局部=>和局部=>帮助器。

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

form_for的工作方式是,它检查模型,看看它是否被持久化,然后做默认的事情来匹配。我个人认为,从edit行动调用form_for将假定update,但它没有。对于任何非持久化模型,form_for将假定动作为create,对于任何持久化模型,则假定动作为update。我相信如果你想的话,你可以重写这个,但我自己还没有试过。

听起来你可能正在做的是显示模型并试图在同一页面上创建新模型。(如果我错了,请包括你的控制器,因为很难说你打算做什么。)你可能需要一个@show_order和一个@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_toformat行,如果他们在那里。)

相关内容

  • 没有找到相关文章

最新更新