0

これを適切にレンダリングして更新するのに最も苦労しています。何が起こっているのかというと、私には多対多の関連付けがあり、関連付け結合テーブルには複数の属性が含まれています。ケースには多くの画面があり、画面には多くのケースがあり、ケースごとにケースの画面を注文できます。私の現在の設定で発生しているもう1つの奇妙な項目は、フォームを送信するたびに、関連付けテーブルが古い関連付け値をクリアしていないことです。新しい値がテーブルに追加されています。

クラス:

class Case < ActiveRecord::Base
    attr_accessible :cases_screens_attributes

    has_many :cases_screens
    has_many :screens, :through => :cases_screens

    accepts_nested_attributes_for :cases_screens, 
                                  :allow_destroy => true,
                                  :reject_if => lambda { |p| p[:screen_id].nil? }
end

class Screen < ActiveRecord::Base
    has_many :cases_screens
    has_many :cases, :through => :cases_screens
end

class CasesScreen < ActiveRecord::Base
    attr_accessible :order

    belongs_to :case
    belongs_to :screen
end

コントローラ:

# GET /cases/1/edit
def edit
    @case = Case.find(params[:id])
    @cases_screens = @case.cases_screens.order("cases_screens.[order] ASC")
    @screens = Screen.where({:active => true})
end

# PUT /cases/1
# PUT /cases/1.json
def update
    @case = Case.find(params[:id])
    @cases_screens = @case.cases_screens.order("cases_screens.[order] ASC")
    @screens = Screen.where({:active => true})

    respond_to do |format|
      if @case.update_attributes(params[:case])
        format.html { redirect_to case_path(@case), :notice => t(:case_successfully_updated) }
        format.json { head :no_content }
      else
        format.html { render :action => "edit" }
        format.json { render :json => @case.errors, :status => :unprocessable_entity }
      end
    end
end

私はfields_forを使用して何の役にも立たないように何度も試みました。これは、現在_form.erb.htmlファイルにあるものです。最終的な目標は、ケースフォームで、各画面の横にチェックボックスが付いたすべての画面のリストを表示することです。各チェックボックスには、「注文」の入力も関連付けられています。送信すると、cases_screensテーブルに適切にデータが入力されます(選択されなくなった場合、古い値は削除されます)。

<div class="controls">

  <% @screens.each do |s| %>

    <label>
      <%= check_box_tag("case[cases_screens_attributes][#{s.id}][screen_id]", s.id, @case.screen_ids.include?(s.id)) %>
      <%= s.name %>
    </label>
      <%= select_tag("case[cases_screens_attributes][#{s.id}][order]", options_for_select(1..@screens.size, 2)) %>
  <% end %>

</div>

私はこれで数日間壁に頭をぶつけてきました、そして私はそれを正しく理解することができないようです。どんな助けでも大歓迎です。

追記:

私は単純なフォームを使用します、私はちょうど次のことをしました:

<%= f.association :screens %>

そして、すべてが期待どおりに機能します(注文属性の更新はありません)。関連付けテーブルが適切にクリーンアップされます。もちろん、これは私を犯人としてネストされた属性の方向に向けていますが、私にはわかりません。

水曜日の更新10:45ここで発生している問題は、cases_screens_idがフォームに存在しないことであると確信しています。通常、クリーンアップ中に、レールはこのIDを使用して以前のエントリをクリーンアップしてから、新しいエントリにデータを入力します。現在存在するcases_screens(ケースに関連付けられている)ではなく@screensをループしているため、各行をクエリせずにIDを取得する方法はありません。

今のところ、私のソリューションでは、cases_screensにbefore_saveメソッドを記述して、cases_screensの現在のエントリをクリーンアップし、新しい値を入力できるようにします。

更新1:15チェックボックスがオンになっている場合にのみレコードが挿入されるように、少なくとも1つの項目に少し近づきました。上記のCaseクラスに更新された:reject_ifを追加しました。値がテーブルにのみ追加される理由、および以前の値が削除されない理由については、まだ解決策がありません。

更新4:00私の最近の試みには、レコードが設定されただけの場合、cases_screensIDを含む隠しフィールドが含まれていました。これには、現在のcases_screen_idを取得するために、ループ内でサブクエリを作成する必要がありました。:reject_ifパラメーターとともに、値が適切に更新されるようになりました。ただし、現在設定されている値は削除できなくなりました。

私がこれを正しく行う方法はありません、それはレールのように感じません。このシナリオは、コントローラーでデータを手動で処理する必要があるシナリオの1つでしょうか?

4

1 に答える 1

0

現時点では、これを設計上の問題にまで絞り込んでいます。

私は今使っています

  <% @case.cases_screens.each do |cs| %>
    <%= hidden_field_tag("case[cases_screens_attributes][#{cs.id}][id]", cs.id) %>
    <%= hidden_field_tag("case[cases_screens_attributes][#{cs.id}][screen_id]", cs.screen_id) %>
    <%= hidden_field_tag("case[cases_screens_attributes][#{cs.id}][_destroy]", 1) %>
    <label><%= check_box_tag("case[cases_screens_attributes][#{cs.id}][_destroy]", 0, @case.cases_screen_ids.include?(cs.id)) %> <%= cs.screen.name %></label>
    <%= text_field_tag("case[cases_screens_attributes][#{cs.id}][ordinality]", cs.ordinality) %>
  <% end %>

これにより、現在設定されているケース/画面のリンクアップのみが表示されます。ユーザーは、別の画面を介してケースに特定の画面を追加する必要があります。

于 2012-12-09T18:30:19.713 に答える