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

どちらも機能せず、無効な text_field について不平を言います。

これを行う最善の方法は何ですか?ありがとう

4

3 に答える 3

1

私はよく知らないがsemantic_form_for、それは通常ののスーパーセットだと思うform_for

動作する方法form_forは、モデルが永続化されているかどうかを確認するためにモデルを検査し、それに一致するようにデフォルトの処理を実行することです。個人的には、アクションform_forからの呼び出しは想定していると思いましたが、そうではありません。アクションは、永続化されていないモデルおよび永続化されたモデルに対するものであると想定します。必要に応じてこれをオーバーライドできると確信していますが、私は自分でこれを実行しようとはしていません。editupdateform_forcreateupdate

モデルを表示し、同じページで新しいモデルを作成しようとしているようです。(私が間違っている場合は、何をしようとしているのかわからないので、コントローラーを含めてください。)コントローラーに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_to(つまり、行がある場合は削除しないformatでください。)

于 2013-01-16T19:48:33.517 に答える
1

問題は、create.js が既存の @order である作成操作の結果から得られた @order を読み取っているため、更新になることです。

1 つの修正: 'if @order.save' create セクションで @order_new = Order.new を使用して新しい @order を作成します。

@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 を新しいインスタンスにする必要がある場合も、同じルールが適用されます。

create.js で @order を使用して何かを実行する場合に備えて、@order を上書きする代わりに @order_new を使用しました。

補足 (他のビューア向け): Rails 3.x の render メソッドは、パーシャル => および 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 に答える