19

これは、私が尋ねた中で最も難しい質問の 1 つかもしれませんが、数日間立ち往生しており、経験豊富な Rails コミュニティからサポートを受けるのが最善だと思いました。

このガイドに大まかに従うダミーアプリに取り組んでいます... ajax/jqueryチュートリアル...

独自のカスタマイズを行うと、このガイドは、「ブランド」(ネストされたモデル「モデル」、「サブモデル」、「スタイル」を含む) 送信フォーム (simple_form を使用) と同じページにブランドのリストを作成するのに役立ちました..これは完全に機能しますただし、フォームとブランドのリストを同じページに配置すると、送信の失敗時に表示されていた適切なインライン検証エラーが失われます (下の画像を参照)。インライン エラーを機能させることができなかったので、レンダリングについてもっと学ぶ必要があることに気付きました..それが、この質問に対する答えを見つけることに固執している理由です。

ここに画像の説明を入力

...そしてここにリストがあります:

ここに画像の説明を入力

以下は index アクションのコントローラーです。

  def index

    #This is for the product listing

    @brands = Brand.all.reverse 

    #This is for the form   

    @brand = Brand.new
    @model = Model.new
    @submodel = Submodel.new
    @style = Style.new

    respond_to do |format|
      format.html
    end
  end

上記のフォームは、ネストされた送信フォームで使用するブランド、モデル、サブモデル、およびスタイルを作成します... 以下は、フォームのコードです。

<%= simple_form_for @brand, :html => { :class => 'form-horizontal' }, :remote => true do |m| %>

  <fieldset style = "margin-top:34px;">
    <legend></legend>
    <%= m.input :name, :label => 'Brand' %>         
    <%= m.simple_fields_for :models, @model do |p| %>    
      <%= p.input :name, :label => 'Model' %>
      <%= p.simple_fields_for :submodels, @submodel do |s| %>
        <%= s.input :name, :label => 'Submodel' %>
        <%= s.simple_fields_for :styles, @style do |ss| %>
          <%= ss.input :name, :label => 'Style' %>
        <% end %>
      <% end %>
    <% end %>

    <div class="form-actions">
      <%= m.submit nil, :class => 'btn btn-primary' %>
      <%= link_to 'Cancel', brands_path, :class => 'btn' %>
    </div>
  </fieldset>
<% end %>

ご覧のとおり、私が使用して:remote => trueいるのは...フォームで新しい「ブランド」を作成するか、フォームでインライン検証エラーをリロードすることです。現時点では、私の作成アクションは次のようになります。

def create
    @brand = Brand.new(params[:brand])

    respond_to do |format|
      if @brand.save
        format.html { redirect_to brands_url, notice: 'Brand was successfully created.' }
        format.json { render json: @brand, status: :created, location: @brand }
        format.js
      else
        format.html { render action: "index" }
        format.json { render json: @brand.errors, status: :unprocessable_entity }
        format.js { render 'reload' }
      end
    end
  end

下に表示されるコードはif @brand.save機能しているようですが、「else」の下のコードは思い通りに機能しません。では、@brand が保存されない場合はどうなるでしょうか? index アクション内のコードが実行され、@brand.errors が json に変換され (simple_form 検証エラーのためだと思います)、reload.js.erb が実行されていると思います。

フォームをリロードしようとして (検証エラーあり)、$("#entryform").load(location.href+" #entryform>*","");reload.js.erb に行を入れました ... 無効なデータをフォームに入れると reload.js.erb が呼び出されますが、発生するのはデータが入力されてインライン検証エラーが発生する代わりに、フォーム フィールドが空白でリロードされます。

私は助けを得るためにここで十分な情報を提供したことを願っています..これに本当に苦労しています。ありがとう!

4

3 に答える 3

30

simple_formフォームをパーシャル (ここでは と呼びます) に配置し、このコードを reload.js.erb に配置する ことで、これを簡素化できると思います。

$("#entryform").html("<%= escape_javascript(render :partial => 'simple_form') %>");

jQuery のload方法には詳しくありませんが、2 番目の要求を行うと思います。レンダリング エラーのキーは、フォームのレンダリング中に使用しているインスタンス変数 ( @brand) であり、作成時に保存しようとしたものと同じである必要があるため、そのエラーを確認できます。これが、エラーをレンダリングする場合にrender代わりに常に使用する理由です。redirect_toリダイレクトを行うと、新しいリクエストが開始されます。つまり@brand、再初期化されます。あなた$(...).load(...)も同じ問題を抱えていると思います。

于 2012-04-07T12:41:43.643 に答える
1

これに関するすべての Q&A に感謝します。それは私を救った。

@tsherif のファイル構造を 1 ノッチ単純化して (既に js ファイルがあると仮定して)、フォーム上で render を直接呼び出し、javascript/coffeescript を介して表示することでこの問題を解決しました。

#immediate_controller
def action_with_modal
  @brand = params[:failed_brand] || Brand.new
end

#brands_controller
def create
  @brand = Brand.new(params[:brand]) 

  respond_to do |format|
    if @brand.save
      ...
    else
      params[:failed_brand] = @brand
      ...
      format.js { render 'simple_form' }
    end
  end
end

#coffeescript
$('form-selectors-here').on 'ajax:error', @reRegister

reRegister: (e, data) =>
  $("div-that-contains-form").html(data.responseText)
于 2014-10-02T20:16:25.800 に答える