0

主に他の 2 つのモデル間の関連付け「コネクタ」であるモデルを作成するために、ネストされたアトリビュート フォームを作成しようとしています。私の場合、モデルは、、、booksおよびawards「コネクタ」モデルを表しますbook_awards。本を編集しているときに、受賞した賞をすばやく選択できるようにしたいと考えています。

私は http://railscasts.com/episodes/196-nested-model-form-part-1 を使用して開始を支援してきましたが、かなり行き詰まっているのではないかと心配しています。

似ていると思われるもう 1 つの SO の質問は 、accepts_nested_attributes_for with find_or_create? です。残念ながら、それは私がやっていることでもありませんし、適応することもできませんでした.

私のモデルはこのように見えます。各モデルには追加の属性や検証などがありますが、わかりやすくするために削除しました。

class Book < ActiveRecord::Base
  has_many :book_awards
  accepts_nested_attributes_for :book_awards, :allow_destroy => true
end

class Award < ActiveRecord::Base
  has_many :book_awards
end

class BookAward < ActiveRecord::Base
  belongs_to :book, :award
end

edit と new のブック コントローラー メソッド、および create と update の失敗例には、行があり@awards = Award.allます。

私の見解では、横にチェックボックスが付いたすべての賞のリストを表示したいと考えています。送信するときに、モデルを更新、作成、または破棄したいと考えていますbook_award。チェック ボックスがオンの場合、既存のモデルを更新するか、存在しない場合は新しいモデルを作成します。チェックボックスが選択されていない場合は、既存のモデルを破棄するか、賞が存在しなかった場合は何もしません。のパーシャルがありbook_awardsます。チェック ボックス セレクターがこのパーシャルに含まれているかどうかはわかりません。

チェックボックスはフックになると思いますが:_destroy、極性が逆になっています。私はこのようなものが基本的にそれを行うと思います:

= f.check_box :_destroy, {}, 0, 1

現在、私はこれをパーシャルに持っていますが、実際にどこに属しているのかわかりません。

次は、現在機能していない私のビューですが、私がやろうとしていることを示すのに役立つかもしれません。をループし、既存のものに対してネストされた属性を設定するためにawardsa を使用します。fields_forひどく醜いですが、ある程度は機能すると思います。ただし、else ケースの開始方法がよくわかりません。

= f.label :awards
- @awards.each do |a|
  - if f.object.awards && f.object.awards.include?(a)
    = f.fields_for :book_awards, f.object.book_award.select{|bas| bas.award == a } do |ba|
      = render 'book_awards', :f => ba, :a => a
  - else
    = fields_for :book_awards do |ba|
      = render 'book_awards', :f => ba, :a => a

既存の賞を最初または最後にリストするのではなく、賞を毎回同じ順序でリストすることをお勧めします (@awardsコントローラーでの私の割り当てはおそらく順序を指定します)。

4

1 に答える 1

0

私は自分の質問に答えるのは嫌いですが、私はついにうまくいくものを見つけました。私が最初にやらなければならなかったのは、railscastに含まれていたクレイジーなオブジェクトに基づいて「新しい」ケースを更新することでした。次に、を手動で設定する必要がありました:child_index。最後に、:_destroyチェックボックスを手動で適切に設定する必要がありました。

.field
  = f.label :awards
  - @awards.each_with_index do |a,i|
    - if exists = (f.object.awards && f.object.awards.include?(a))
      - new_ba = f.object.book_awards.select{|s| s.award == a}
    - else
      - new_ba = f.object.class.reflect_on_association(:book_awards).klass.new
    = f.fields_for :book_awards, new_ba, :child_index => i do |ba|
      = render 'book_awards', :f => ba, :a => a, :existing => exists

私の部分は次のようになります:

.field
  = f.check_box :_destroy, {:checked => existing}, 0, 1
  = f.label a.name
  = f.hidden_field :award_id, :value => a.id
  = f.label :year
  = f.number_field :year

ひどくきれいではありませんが、私が望んでいたことを正確に実行しているようです。

于 2012-11-09T00:36:18.683 に答える