【问题标题】:Deeply nested Rails forms using belong_to not working?使用belong_to 的深度嵌套Rails 表单不起作用?
【发布时间】:2010-09-23 23:38:10
【问题描述】:

我正在处理一个杂乱无章的表单,其中必须管理具有两级嵌套的部分。它几乎可以工作,但是有一个障碍,我唯一能看到的与其他有效的深层嵌套形式不同的是,有一个belongs_to 关系而不是has_many。以下是模型:

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。有问题的表单是创建/编辑一个事件,带有一个动态的“添加公司”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 假设已经有一个条目,但是当然它没有找到一个。这看起来很奇怪,因为显然我需要传入一个 ID 才能创建一个新的 CompanyEvent 条目。所以,我猜我错过了什么。

我发现工作的示例似乎都使用 has_many 关系一直嵌套,而在这种情况下它是一个belongs_to,我想知道这是否是问题的根源。任何想法将不胜感激......

【问题讨论】:

    标签: ruby-on-rails nested-forms belongs-to


    【解决方案1】:

    这是我在类似问题中发布的另一种可能的解决方案: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
    

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,似乎 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}}
      

      但是解决这个问题很简单,如果你的香蕉已经是持久的,你不需要在你的表单中设置任何嵌套属性,你只需要在猴子表单上有一个带有香蕉 ID 的隐藏字段,这将导致类似:

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

      这样保存就好了。

      【讨论】:

      • 我没有尝试代码,但是如果你有accepts_nested_attributes_for :monkey,你的例子不应该是banana.attributes = {:monkey_attributes ...} 吗? monkey.attributes = {:banana_attributes ...} 看起来行不通。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-17
      • 2015-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多