6

私は、特に 2 レベルのネスティングでセクションを管理する必要がある厄介なフォームに取り組んでいます。ほとんど機能していますが、障害があり、機能する他の深くネストされたフォームと異なる唯一のことは、has_many ではなく、begs_to 関係があることです。モデルは次のとおりです。

Event
  has_many :company_events, :dependent => :destroy
  accepts_nested_attributes_for :company_events

CompanyEvent
  belongs_to :company
  accepts_nested_attributes_for :company, :update_only => true
  belongs_to :event
  belongs_to :event_type

Company
  has_many :company_events
  has_many :events, :through => :company_events

これは、リンク テーブル company_events を介したかなり標準的な多対多の関係です。問題のフォームは、動的な「Add Company」Javascript ボタンを使用してイベントを作成/編集しています。ほとんどすべて Ryan Bates のスクリーンキャストと GitHub リポジトリに基づいています。

メインフォーム:

<table id="companies">
  <tr><th>Company Name</th></tr>
  <% f.fields_for :company_events do |builder| %>
    <%= render 'company_event_fields', :f => builder, :f_o => nil %>
  <% end -%>
</table>
<p><br/><%= link_to_add_fields "Add Company", f, :company_events, "events" %></p>

そして、含まれているフォームは次のとおりです。注意すべき重要な点は、企業 ID が Javascript の更新によって設定されることです。これは長くなるため、ここには含めません。基本的に、ユーザーが名前の入力を開始すると、オートコンプリート リストが表示され、名前をクリックすると、会社名と ID の両方がフォームに設定されます。

<tr class="company_event_fields">
  <td>
    <% f.fields_for(:company) do |company_form| -%>
      <%= company_form.text_field :name, :size => 80 %>
      <%= company_form.hidden_field :id %>
    <% end -%>
  </td>
  <td>
    <%= f.hidden_field :_destroy %>
    <%= link_to_function "remove", "remove_co_fields(this)" %>
  </td>
</tr>

既存のレコードを更新すると、すべてが正常に機能します。ただし、新しく作成したレコードでフォームを保存しようとすると、次のようになります。

ActiveRecord::RecordNotFound in EventsController#update

Couldn't find Company with ID=12345 for CompanyEvent with ID=

スタックトレースを使用:

/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/nested_attributes.rb:401:in `raise_nested_attributes_record_not_found'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/nested_attributes.rb:289:in `assign_nested_attributes_for_one_to_one_association'
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/nested_attributes.rb:244:in `company_attributes='
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2906:in `send'

nested_attributes のコードを調べて、デバッガーで実行しました。Company.id があるため、ActiveRecord は既にエントリがあると想定していますが、もちろんエントリが見つかりません。新しい CompanyEvent エントリを作成するために ID を渡す必要があるのは明らかなので、これは非常に奇妙に思えます。だから、私は何かが欠けていると思います。

私が見つけたすべての例は、has_many リレーションシップを使用してネストされているように見えますが、この場合はbelongs_to であり、それが問題の原因であるかどうか疑問に思っています。どんなアイデアでも大歓迎です...

4

2 に答える 2

13

同様の質問に投稿した別の解決策を次に示します: https://stackoverflow.com/a/12064875/47185

このようなもの...

  accepts_nested_attributes_for :company
  def company_attributes=(attributes)
    if attributes['id'].present?
      self.company = Company.find(attributes['id'])
    end
    super
  end
于 2012-08-22T23:07:27.173 に答える
4

私は同じ問題に遭遇しました.Railsはこのようなネストされたモデルの使用をサポートしていないようです.存在するネストされたモデルで新しいオブジェクトを保存することはできません,例えば,この状況を想像してください:

class Monkey < ActiveRecord::Base
end
class Banana < ActiveRecord::Base
    belongs_to :monkey
    accepts_nested_attributes_for :monkey
end

コンソールで試すと、これは機能しません。

banana = Banana.create!
monkey = Monkey.new
monkey.attributes = {:banana_attributes => { :id => banana.id}}

しかし、これを回避するのは簡単です。バナナがすでに永続的である場合、フォームでネストされた属性を設定する必要はありません。モンキーフォームにbanana_idの非表示フィールドが必要なだけで、次のようになります。

monkey.attributes = {:banana_id => banana.id}

そして、それはうまく保存されます。

于 2010-12-10T16:44:43.583 に答える